00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "qgpgmecryptoconfig.h"
00034 #include <kdebug.h>
00035 #include <kprocio.h>
00036 #include <errno.h>
00037 #include <kmessagebox.h>
00038 #include <klocale.h>
00039
00040 #include <assert.h>
00041 #include <ktempfile.h>
00042 #include <qfile.h>
00043 #include <stdlib.h>
00044 #include <qtextcodec.h>
00045
00046
00047
00048 static bool s_duringClear = false;
00049
00050 #define GPGCONF_FLAG_GROUP 1
00051 #define GPGCONF_FLAG_OPTIONAL 2
00052 #define GPGCONF_FLAG_LIST 4
00053 #define GPGCONF_FLAG_RUNTIME 8
00054 #define GPGCONF_FLAG_DEFAULT 16 // fixed default value available
00055 #define GPGCONF_FLAG_DEFAULT_DESC 32 // runtime default value available
00056 #define GPGCONF_FLAG_NOARG_DESC 64 // option with optional arg; special meaning if no arg set
00057
00058
00059 QGpgMECryptoConfig::QGpgMECryptoConfig()
00060 : mComponents( 7 ), mParsed( false )
00061 {
00062 mComponents.setAutoDelete( true );
00063 }
00064
00065 QGpgMECryptoConfig::~QGpgMECryptoConfig()
00066 {
00067 }
00068
00069 void QGpgMECryptoConfig::runGpgConf( bool showErrors )
00070 {
00071
00072
00073 KProcIO proc( QTextCodec::codecForName( "utf8" ) );
00074 proc << "gpgconf";
00075 proc << "--list-components";
00076
00077 QObject::connect( &proc, SIGNAL( readReady(KProcIO*) ),
00078 this, SLOT( slotCollectStdOut(KProcIO*) ) );
00079
00080
00081 int rc = 0;
00082 if ( !proc.start( KProcess::Block ) )
00083 rc = -1;
00084 else
00085 rc = ( proc.normalExit() ) ? proc.exitStatus() : -2 ;
00086
00087
00088 if ( showErrors && rc != 0 ) {
00089 QString wmsg = i18n("<qt>Failed to execute gpgconf:<br>%1</qt>");
00090 if ( rc == -1 )
00091 wmsg = wmsg.arg( i18n( "program not found" ) );
00092 else if ( rc == -2 )
00093 wmsg = wmsg.arg( i18n( "program cannot be executed" ) );
00094 else
00095 wmsg = wmsg.arg( strerror(rc) );
00096 kdWarning(5150) << wmsg << endl;
00097 KMessageBox::error(0, wmsg);
00098 }
00099 mParsed = true;
00100 }
00101
00102 void QGpgMECryptoConfig::slotCollectStdOut( KProcIO* proc )
00103 {
00104 QString line;
00105 int result;
00106 while( ( result = proc->readln(line) ) != -1 ) {
00107
00108
00109 QStringList lst = QStringList::split( ':', line, true );
00110 if ( lst.count() >= 2 ) {
00111 mComponents.insert( lst[0], new QGpgMECryptoConfigComponent( this, lst[0], lst[1] ) );
00112 } else {
00113 kdWarning(5150) << "Parse error on gpgconf --list-components output: " << line << endl;
00114 }
00115 }
00116 }
00117
00118 QStringList QGpgMECryptoConfig::componentList() const
00119 {
00120 if ( !mParsed )
00121 const_cast<QGpgMECryptoConfig*>( this )->runGpgConf( true );
00122 QDictIterator<QGpgMECryptoConfigComponent> it( mComponents );
00123 QStringList names;
00124 for( ; it.current(); ++it )
00125 names.push_back( it.currentKey() );
00126 return names;
00127 }
00128
00129 Kleo::CryptoConfigComponent* QGpgMECryptoConfig::component( const QString& name ) const
00130 {
00131 if ( !mParsed )
00132 const_cast<QGpgMECryptoConfig*>( this )->runGpgConf( false );
00133 return mComponents.find( name );
00134 }
00135
00136 void QGpgMECryptoConfig::sync( bool runtime )
00137 {
00138 QDictIterator<QGpgMECryptoConfigComponent> it( mComponents );
00139 for( ; it.current(); ++it )
00140 it.current()->sync( runtime );
00141 }
00142
00143 void QGpgMECryptoConfig::clear()
00144 {
00145 s_duringClear = true;
00146 mComponents.clear();
00147 s_duringClear = false;
00148 mParsed = false;
00149 }
00150
00152
00153 QGpgMECryptoConfigComponent::QGpgMECryptoConfigComponent( QGpgMECryptoConfig*, const QString& name, const QString& description )
00154 : mGroups( 7 ), mName( name ), mDescription( description )
00155 {
00156 mGroups.setAutoDelete( true );
00157 runGpgConf();
00158 }
00159
00160 QGpgMECryptoConfigComponent::~QGpgMECryptoConfigComponent()
00161 {
00162 }
00163
00164 void QGpgMECryptoConfigComponent::runGpgConf()
00165 {
00166
00167
00168 KProcIO proc( QTextCodec::codecForName( "utf8" ) );
00169 proc << "gpgconf";
00170 proc << "--list-options";
00171 proc << mName;
00172
00173
00174
00175 QObject::connect( &proc, SIGNAL( readReady(KProcIO*) ),
00176 this, SLOT( slotCollectStdOut(KProcIO*) ) );
00177 mCurrentGroup = 0;
00178
00179
00180 int rc = 0;
00181 if ( !proc.start( KProcess::Block ) )
00182 rc = -1;
00183 else
00184 rc = ( proc.normalExit() ) ? proc.exitStatus() : -1 ;
00185
00186 if( rc != 0 )
00187 kdWarning(5150) << "Running 'gpgconf --list-options " << mName << "' failed. " << strerror( rc ) << ", but try that command to see the real output" << endl;
00188 else {
00189 if ( mCurrentGroup && !mCurrentGroup->mEntries.isEmpty() )
00190 mGroups.insert( mCurrentGroupName, mCurrentGroup );
00191 }
00192 }
00193
00194 void QGpgMECryptoConfigComponent::slotCollectStdOut( KProcIO* proc )
00195 {
00196 QString line;
00197 int result;
00198 while( ( result = proc->readln(line) ) != -1 ) {
00199
00200
00201 const QStringList lst = QStringList::split( ':', line, true );
00202 if ( lst.count() >= 10 ) {
00203 const int flags = lst[1].toInt();
00204 const int level = lst[2].toInt();
00205 if ( level > 2 )
00206 continue;
00207 if ( flags & GPGCONF_FLAG_GROUP ) {
00208 if ( mCurrentGroup && !mCurrentGroup->mEntries.isEmpty() )
00209 mGroups.insert( mCurrentGroupName, mCurrentGroup );
00210
00211
00212 mCurrentGroup = new QGpgMECryptoConfigGroup( lst[0], lst[3], level );
00213 mCurrentGroupName = lst[0];
00214 } else {
00215
00216 if ( !mCurrentGroup ) {
00217 mCurrentGroup = new QGpgMECryptoConfigGroup( "<nogroup>", QString::null, 0 );
00218 mCurrentGroupName = "<nogroup>";
00219 }
00220 mCurrentGroup->mEntries.insert( lst[0], new QGpgMECryptoConfigEntry( lst ) );
00221 }
00222 } else {
00223
00224
00225
00226
00227 }
00228 }
00229 }
00230
00231 QStringList QGpgMECryptoConfigComponent::groupList() const
00232 {
00233 QDictIterator<QGpgMECryptoConfigGroup> it( mGroups );
00234 QStringList names;
00235 for( ; it.current(); ++it )
00236 names.push_back( it.currentKey() );
00237 return names;
00238 }
00239
00240 Kleo::CryptoConfigGroup* QGpgMECryptoConfigComponent::group(const QString& name ) const
00241 {
00242 return mGroups.find( name );
00243 }
00244
00245 void QGpgMECryptoConfigComponent::sync( bool runtime )
00246 {
00247 KTempFile tmpFile;
00248 tmpFile.setAutoDelete( true );
00249
00250 QValueList<QGpgMECryptoConfigEntry *> dirtyEntries;
00251
00252
00253 QDictIterator<QGpgMECryptoConfigGroup> groupit( mGroups );
00254 for( ; groupit.current(); ++groupit ) {
00255 QDictIterator<QGpgMECryptoConfigEntry> it( groupit.current()->mEntries );
00256 for( ; it.current(); ++it ) {
00257 if ( it.current()->isDirty() ) {
00258
00259 QString line = it.currentKey();
00260 if ( it.current()->isSet() ) {
00261 line += ":0:";
00262 line += it.current()->outputString();
00263 } else {
00264 line += ":16:";
00265 }
00266 line += '\n';
00267 QCString line8bit = line.utf8();
00268 tmpFile.file()->writeBlock( line8bit.data(), line8bit.size()-1 );
00269 dirtyEntries.append( it.current() );
00270 }
00271 }
00272 }
00273 tmpFile.close();
00274 if ( dirtyEntries.isEmpty() )
00275 return;
00276
00277
00278 QString commandLine = "gpgconf";
00279 if ( runtime )
00280 commandLine += " --runtime";
00281 commandLine += " --change-options ";
00282 commandLine += KProcess::quote( mName );
00283 commandLine += " < ";
00284 commandLine += KProcess::quote( tmpFile.name() );
00285
00286
00287
00288
00289 KProcess proc;
00290 proc.setUseShell( true );
00291 proc << commandLine;
00292
00293
00294 int rc = 0;
00295 if ( !proc.start( KProcess::Block ) )
00296 rc = -1;
00297 else
00298 rc = ( proc.normalExit() ) ? proc.exitStatus() : -1 ;
00299
00300 if ( rc == -1 )
00301 {
00302 QString wmsg = i18n( "Could not start gpgconf\nCheck that gpgconf is in the PATH and that it can be started" );
00303 kdWarning(5150) << wmsg << endl;
00304 KMessageBox::error(0, wmsg);
00305 }
00306 else if( rc != 0 )
00307 {
00308 QString wmsg = i18n( "Error from gpgconf while saving configuration: %1" ).arg( strerror( rc ) );
00309 kdWarning(5150) << k_funcinfo << ":" << strerror( rc ) << endl;
00310 KMessageBox::error(0, wmsg);
00311 }
00312 else
00313 {
00314 QValueList<QGpgMECryptoConfigEntry *>::Iterator it = dirtyEntries.begin();
00315 for( ; it != dirtyEntries.end(); ++it ) {
00316 (*it)->setDirty( false );
00317 }
00318 }
00319 }
00320
00322
00323 QGpgMECryptoConfigGroup::QGpgMECryptoConfigGroup( const QString & name, const QString& description, int level )
00324 : mEntries( 29 ),
00325 mName( name ),
00326 mDescription( description ),
00327 mLevel( static_cast<Kleo::CryptoConfigEntry::Level>( level ) )
00328 {
00329 mEntries.setAutoDelete( true );
00330 }
00331
00332 QStringList QGpgMECryptoConfigGroup::entryList() const
00333 {
00334 QDictIterator<QGpgMECryptoConfigEntry> it( mEntries );
00335 QStringList names;
00336 for( ; it.current(); ++it )
00337 names.push_back( it.currentKey() );
00338 return names;
00339 }
00340
00341 Kleo::CryptoConfigEntry* QGpgMECryptoConfigGroup::entry( const QString& name ) const
00342 {
00343 return mEntries.find( name );
00344 }
00345
00347
00348 static QString gpgconf_unescape( const QString& str )
00349 {
00350
00351 return KURL::decode_string( str, 106 );
00352 }
00353
00354 static QString gpgconf_escape( const QString& str )
00355 {
00356
00357 QString enc = KURL::encode_string( str, 106 );
00358
00359 enc.replace( ',', "%2c" );
00360 return enc;
00361 }
00362
00363 static QString urlpart_encode( const QString& str )
00364 {
00365 QString enc( str );
00366 enc.replace( '%', "%25" );
00367 enc.replace( ':', "%3a" );
00368
00369 return enc;
00370 }
00371
00372 static QString urlpart_decode( const QString& str )
00373 {
00374 return KURL::decode_string( str );
00375 }
00376
00377
00378 static Kleo::CryptoConfigEntry::ArgType knownArgType( int argType, bool& ok ) {
00379 ok = true;
00380 switch( argType ) {
00381 case 0:
00382 return Kleo::CryptoConfigEntry::ArgType_None;
00383 case 1:
00384 return Kleo::CryptoConfigEntry::ArgType_String;
00385 case 2:
00386 return Kleo::CryptoConfigEntry::ArgType_Int;
00387 case 3:
00388 return Kleo::CryptoConfigEntry::ArgType_UInt;
00389 case 32:
00390 return Kleo::CryptoConfigEntry::ArgType_Path;
00391 case 33:
00392 return Kleo::CryptoConfigEntry::ArgType_LDAPURL;
00393 default:
00394 ok = false;
00395 return Kleo::CryptoConfigEntry::ArgType_None;
00396 }
00397 }
00398
00399 QGpgMECryptoConfigEntry::QGpgMECryptoConfigEntry( const QStringList& parsedLine )
00400 {
00401
00402 assert( parsedLine.count() >= 10 );
00403 QStringList::const_iterator it = parsedLine.begin();
00404 mName = *it++;
00405 mFlags = (*it++).toInt();
00406 mLevel = (*it++).toInt();
00407 mDescription = *it++;
00408 bool ok;
00409
00410 mRealArgType = (*it++).toInt();
00411 mArgType = knownArgType( mRealArgType, ok );
00412 if ( !ok && !(*it).isEmpty() ) {
00413
00414 mRealArgType = (*it).toInt();
00415 mArgType = knownArgType( mRealArgType, ok );
00416 }
00417 if ( !ok )
00418 kdWarning(5150) << "Unsupported datatype: " << parsedLine[4] << " : " << *it << " for " << parsedLine[0] << endl;
00419 ++it;
00420 ++it;
00421
00422 mSet = false;
00423 QString value;
00424 if ( mFlags & GPGCONF_FLAG_DEFAULT ) {
00425 value = *it;
00426 mDefaultValue = stringToValue( value, true );
00427 }
00428 ++it;
00429 ++it;
00430
00431
00432 if ( !(*it).isEmpty() ) {
00433 mSet = true;
00434 value = *it;
00435 mValue = stringToValue( value, true );
00436 }
00437 else {
00438 mValue = mDefaultValue;
00439 }
00440
00441 mDirty = false;
00442 }
00443
00444 QVariant QGpgMECryptoConfigEntry::stringToValue( const QString& str, bool unescape ) const
00445 {
00446 bool isString = isStringType();
00447
00448 if ( isList() ) {
00449 QValueList<QVariant> lst;
00450 QStringList items = QStringList::split( ',', str );
00451 for( QStringList::const_iterator valit = items.begin(); valit != items.end(); ++valit ) {
00452 QString val = *valit;
00453 if ( isString ) {
00454 if ( val.isEmpty() ) {
00455 lst << QString::null;
00456 continue;
00457 }
00458 else if ( unescape ) {
00459 if( val[0] != '"' )
00460 kdWarning(5150) << "String value should start with '\"' : " << val << endl;
00461 val = val.mid( 1 );
00462 }
00463 }
00464 lst << QVariant( unescape ? gpgconf_unescape( val ) : val );
00465 }
00466 return lst;
00467 } else {
00468 QString val( str );
00469 if ( isString ) {
00470 if ( val.isEmpty() )
00471 return QVariant( QString::null );
00472 else if ( unescape ) {
00473 Q_ASSERT( val[0] == '"' );
00474 val = val.mid( 1 );
00475 }
00476 }
00477 return QVariant( unescape ? gpgconf_unescape( val ) : val );
00478 }
00479 }
00480
00481 QGpgMECryptoConfigEntry::~QGpgMECryptoConfigEntry()
00482 {
00483 #ifndef NDEBUG
00484 if ( !s_duringClear && mDirty )
00485 kdWarning(5150) << "Deleting a QGpgMECryptoConfigEntry that was modified (" << mDescription << ")\n"
00486 << "You forgot to call sync() (to commit) or clear() (to discard)" << endl;
00487 #endif
00488 }
00489
00490 bool QGpgMECryptoConfigEntry::isOptional() const
00491 {
00492 return mFlags & GPGCONF_FLAG_OPTIONAL;
00493 }
00494
00495 bool QGpgMECryptoConfigEntry::isList() const
00496 {
00497 return mFlags & GPGCONF_FLAG_LIST;
00498 }
00499
00500 bool QGpgMECryptoConfigEntry::isRuntime() const
00501 {
00502 return mFlags & GPGCONF_FLAG_RUNTIME;
00503 }
00504
00505 bool QGpgMECryptoConfigEntry::isSet() const
00506 {
00507 return mSet;
00508 }
00509
00510 bool QGpgMECryptoConfigEntry::boolValue() const
00511 {
00512 Q_ASSERT( mArgType == ArgType_None );
00513 Q_ASSERT( !isList() );
00514 return mValue.toBool();
00515 }
00516
00517 QString QGpgMECryptoConfigEntry::stringValue() const
00518 {
00519 return toString( false );
00520 }
00521
00522 int QGpgMECryptoConfigEntry::intValue() const
00523 {
00524 Q_ASSERT( mArgType == ArgType_Int );
00525 Q_ASSERT( !isList() );
00526 return mValue.toInt();
00527 }
00528
00529 unsigned int QGpgMECryptoConfigEntry::uintValue() const
00530 {
00531 Q_ASSERT( mArgType == ArgType_UInt );
00532 Q_ASSERT( !isList() );
00533 return mValue.toUInt();
00534 }
00535
00536 static KURL parseURL( int mRealArgType, const QString& str )
00537 {
00538 if ( mRealArgType == 33 ) {
00539
00540 QStringList items = QStringList::split( ':', str, true );
00541 if ( items.count() == 5 ) {
00542 QStringList::const_iterator it = items.begin();
00543 KURL url;
00544 url.setProtocol( "ldap" );
00545 url.setHost( urlpart_decode( *it++ ) );
00546 url.setPort( (*it++).toInt() );
00547 url.setPath( "/" );
00548 url.setUser( urlpart_decode( *it++ ) );
00549 url.setPass( urlpart_decode( *it++ ) );
00550 url.setQuery( urlpart_decode( *it ) );
00551 return url;
00552 } else
00553 kdWarning(5150) << "parseURL: malformed LDAP server: " << str << endl;
00554 }
00555
00556 return KURL( str );
00557 }
00558
00559
00560 static QString splitURL( int mRealArgType, const KURL& url )
00561 {
00562 if ( mRealArgType == 33 ) {
00563
00564 Q_ASSERT( url.protocol() == "ldap" );
00565 return urlpart_encode( url.host() ) + ":" +
00566 QString::number( url.port() ) + ":" +
00567 urlpart_encode( url.user() ) + ":" +
00568 urlpart_encode( url.pass() ) + ":" +
00569
00570
00571 urlpart_encode( KURL::decode_string( url.query().mid(1) ) );
00572 }
00573 return url.path();
00574 }
00575
00576 KURL QGpgMECryptoConfigEntry::urlValue() const
00577 {
00578 Q_ASSERT( mArgType == ArgType_Path || mArgType == ArgType_URL || mArgType == ArgType_LDAPURL );
00579 Q_ASSERT( !isList() );
00580 QString str = mValue.toString();
00581 if ( mArgType == ArgType_Path )
00582 {
00583 KURL url;
00584 url.setPath( str );
00585 return url;
00586 }
00587 return parseURL( mRealArgType, str );
00588 }
00589
00590 unsigned int QGpgMECryptoConfigEntry::numberOfTimesSet() const
00591 {
00592 Q_ASSERT( mArgType == ArgType_None );
00593 Q_ASSERT( isList() );
00594 return mValue.toUInt();
00595 }
00596
00597 QStringList QGpgMECryptoConfigEntry::stringValueList() const
00598 {
00599 Q_ASSERT( isStringType() );
00600 Q_ASSERT( isList() );
00601 return mValue.toStringList();
00602 }
00603
00604 QValueList<int> QGpgMECryptoConfigEntry::intValueList() const
00605 {
00606 Q_ASSERT( mArgType == ArgType_Int );
00607 Q_ASSERT( isList() );
00608 QValueList<int> ret;
00609 QValueList<QVariant> lst = mValue.toList();
00610 for( QValueList<QVariant>::const_iterator it = lst.begin(); it != lst.end(); ++it ) {
00611 ret.append( (*it).toInt() );
00612 }
00613 return ret;
00614 }
00615
00616 QValueList<unsigned int> QGpgMECryptoConfigEntry::uintValueList() const
00617 {
00618 Q_ASSERT( mArgType == ArgType_UInt );
00619 Q_ASSERT( isList() );
00620 QValueList<unsigned int> ret;
00621 QValueList<QVariant> lst = mValue.toList();
00622 for( QValueList<QVariant>::const_iterator it = lst.begin(); it != lst.end(); ++it ) {
00623 ret.append( (*it).toUInt() );
00624 }
00625 return ret;
00626 }
00627
00628 KURL::List QGpgMECryptoConfigEntry::urlValueList() const
00629 {
00630 Q_ASSERT( mArgType == ArgType_Path || mArgType == ArgType_URL || mArgType == ArgType_LDAPURL );
00631 Q_ASSERT( isList() );
00632 QStringList lst = mValue.toStringList();
00633
00634 KURL::List ret;
00635 for( QStringList::const_iterator it = lst.begin(); it != lst.end(); ++it ) {
00636 if ( mArgType == ArgType_Path ) {
00637 KURL url;
00638 url.setPath( *it );
00639 ret << url;
00640 } else {
00641 ret << parseURL( mRealArgType, *it );
00642 }
00643 }
00644 return ret;
00645 }
00646
00647 void QGpgMECryptoConfigEntry::resetToDefault()
00648 {
00649 mSet = false;
00650 mDirty = true;
00651 if ( mFlags & GPGCONF_FLAG_DEFAULT )
00652 mValue = mDefaultValue;
00653 else if ( mArgType == ArgType_None )
00654 mValue = false;
00655 }
00656
00657 void QGpgMECryptoConfigEntry::setBoolValue( bool b )
00658 {
00659 Q_ASSERT( mArgType == ArgType_None );
00660 Q_ASSERT( !isList() );
00661
00662
00663 mValue = b;
00664 mSet = b;
00665 mDirty = true;
00666 }
00667
00668 void QGpgMECryptoConfigEntry::setStringValue( const QString& str )
00669 {
00670 mValue = stringToValue( str, false );
00671
00672
00673
00674 if ( str.isEmpty() && !isOptional() )
00675 mSet = false;
00676 else
00677 mSet = true;
00678 mDirty = true;
00679 }
00680
00681 void QGpgMECryptoConfigEntry::setIntValue( int i )
00682 {
00683 Q_ASSERT( mArgType == ArgType_Int );
00684 Q_ASSERT( !isList() );
00685 mValue = i;
00686 mSet = true;
00687 mDirty = true;
00688 }
00689
00690 void QGpgMECryptoConfigEntry::setUIntValue( unsigned int i )
00691 {
00692 mValue = i;
00693 mSet = true;
00694 mDirty = true;
00695 }
00696
00697 void QGpgMECryptoConfigEntry::setURLValue( const KURL& url )
00698 {
00699 QString str = splitURL( mRealArgType, url );
00700 if ( str.isEmpty() && !isOptional() )
00701 mSet = false;
00702 else
00703 mSet = true;
00704 mValue = str;
00705 mDirty = true;
00706 }
00707
00708 void QGpgMECryptoConfigEntry::setNumberOfTimesSet( unsigned int i )
00709 {
00710 Q_ASSERT( mArgType == ArgType_None );
00711 Q_ASSERT( isList() );
00712 setUIntValue( i );
00713 }
00714
00715 void QGpgMECryptoConfigEntry::setStringValueList( const QStringList& lst )
00716 {
00717 mValue = lst;
00718 if ( lst.isEmpty() && !isOptional() )
00719 mSet = false;
00720 else
00721 mSet = true;
00722 mDirty = true;
00723 }
00724
00725 void QGpgMECryptoConfigEntry::setIntValueList( const QValueList<int>& lst )
00726 {
00727 QValueList<QVariant> ret;
00728 for( QValueList<int>::const_iterator it = lst.begin(); it != lst.end(); ++it ) {
00729 ret << QVariant( *it );
00730 }
00731 mValue = ret;
00732 if ( ret.isEmpty() && !isOptional() )
00733 mSet = false;
00734 else
00735 mSet = true;
00736 mDirty = true;
00737 }
00738
00739 void QGpgMECryptoConfigEntry::setUIntValueList( const QValueList<unsigned int>& lst )
00740 {
00741 QValueList<QVariant> ret;
00742 for( QValueList<unsigned int>::const_iterator it = lst.begin(); it != lst.end(); ++it ) {
00743 ret << QVariant( *it );
00744 }
00745 if ( ret.isEmpty() && !isOptional() )
00746 mSet = false;
00747 else
00748 mSet = true;
00749 mValue = ret;
00750 mDirty = true;
00751 }
00752
00753 void QGpgMECryptoConfigEntry::setURLValueList( const KURL::List& urls )
00754 {
00755 QStringList lst;
00756 for( KURL::List::const_iterator it = urls.begin(); it != urls.end(); ++it ) {
00757 lst << splitURL( mRealArgType, *it );
00758 }
00759 mValue = lst;
00760 if ( lst.isEmpty() && !isOptional() )
00761 mSet = false;
00762 else
00763 mSet = true;
00764 mDirty = true;
00765 }
00766
00767 QString QGpgMECryptoConfigEntry::toString( bool escape ) const
00768 {
00769
00770 if ( isStringType() ) {
00771 if ( mValue.isNull() )
00772 return QString::null;
00773 else if ( isList() ) {
00774 QStringList lst = mValue.toStringList();
00775 if ( escape ) {
00776 for( QStringList::iterator it = lst.begin(); it != lst.end(); ++it ) {
00777 if ( !(*it).isNull() )
00778 *it = gpgconf_escape( *it ).prepend( "\"" );
00779 }
00780 }
00781 QString res = lst.join( "," );
00782 kdDebug(5150) << "toString: " << res << endl;
00783 return res;
00784 } else {
00785 QString res = mValue.toString();
00786 if ( escape )
00787 res = gpgconf_escape( res ).prepend( "\"" );
00788 return res;
00789 }
00790 }
00791 if ( !isList() )
00792 {
00793 if ( mArgType == ArgType_None ) {
00794 return mValue.toBool() ? QString::fromLatin1( "1" ) : QString::null;
00795 } else {
00796 Q_ASSERT( mArgType == ArgType_Int || mArgType == ArgType_UInt );
00797 return mValue.toString();
00798 }
00799 }
00800
00801
00802 if ( mArgType == ArgType_None )
00803 return QString::number( numberOfTimesSet() );
00804 QStringList ret;
00805 QValueList<QVariant> lst = mValue.toList();
00806 for( QValueList<QVariant>::const_iterator it = lst.begin(); it != lst.end(); ++it ) {
00807 ret << (*it).toString();
00808 }
00809 return ret.join( "," );
00810 }
00811
00812 QString QGpgMECryptoConfigEntry::outputString() const
00813 {
00814 Q_ASSERT( mSet );
00815 return toString( true );
00816 }
00817
00818 bool QGpgMECryptoConfigEntry::isStringType() const
00819 {
00820 return ( mArgType == Kleo::CryptoConfigEntry::ArgType_String
00821 || mArgType == Kleo::CryptoConfigEntry::ArgType_Path
00822 || mArgType == Kleo::CryptoConfigEntry::ArgType_URL
00823 || mArgType == Kleo::CryptoConfigEntry::ArgType_LDAPURL );
00824 }
00825
00826 void QGpgMECryptoConfigEntry::setDirty( bool b )
00827 {
00828 mDirty = b;
00829 }
00830
00831 #include "qgpgmecryptoconfig.moc"