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 QStringList lst = QStringList::split( ':', line, true );
00202 if ( lst.count() >= 10 ) {
00203 int flags = lst[1].toInt();
00204 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[3], level );
00213 mCurrentGroupName = lst[0];
00214 } else {
00215
00216 if ( !mCurrentGroup ) {
00217 mCurrentGroup = new QGpgMECryptoConfigGroup( 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& description, int level )
00324 : mEntries( 29 ),
00325 mDescription( description ),
00326 mLevel( static_cast<Kleo::CryptoConfigEntry::Level>( level ) )
00327 {
00328 mEntries.setAutoDelete( true );
00329 }
00330
00331 QStringList QGpgMECryptoConfigGroup::entryList() const
00332 {
00333 QDictIterator<QGpgMECryptoConfigEntry> it( mEntries );
00334 QStringList names;
00335 for( ; it.current(); ++it )
00336 names.push_back( it.currentKey() );
00337 return names;
00338 }
00339
00340 Kleo::CryptoConfigEntry* QGpgMECryptoConfigGroup::entry( const QString& name ) const
00341 {
00342 return mEntries.find( name );
00343 }
00344
00346
00347 static QString gpgconf_unescape( const QString& str )
00348 {
00349
00350 return KURL::decode_string( str, 106 );
00351 }
00352
00353 static QString gpgconf_escape( const QString& str )
00354 {
00355
00356 QString enc = KURL::encode_string( str, 106 );
00357
00358 enc.replace( ',', "%2c" );
00359 return enc;
00360 }
00361
00362 static QString urlpart_encode( const QString& str )
00363 {
00364 QString enc( str );
00365 enc.replace( '%', "%25" );
00366 enc.replace( ':', "%3a" );
00367
00368 return enc;
00369 }
00370
00371 static QString urlpart_decode( const QString& str )
00372 {
00373 return KURL::decode_string( str );
00374 }
00375
00376
00377 static Kleo::CryptoConfigEntry::ArgType knownArgType( int argType, bool& ok ) {
00378 ok = true;
00379 switch( argType ) {
00380 case 0:
00381 return Kleo::CryptoConfigEntry::ArgType_None;
00382 case 1:
00383 return Kleo::CryptoConfigEntry::ArgType_String;
00384 case 2:
00385 return Kleo::CryptoConfigEntry::ArgType_Int;
00386 case 3:
00387 return Kleo::CryptoConfigEntry::ArgType_UInt;
00388 case 32:
00389 return Kleo::CryptoConfigEntry::ArgType_Path;
00390 case 33:
00391 return Kleo::CryptoConfigEntry::ArgType_LDAPURL;
00392 default:
00393 ok = false;
00394 return Kleo::CryptoConfigEntry::ArgType_None;
00395 }
00396 }
00397
00398 QGpgMECryptoConfigEntry::QGpgMECryptoConfigEntry( const QStringList& parsedLine )
00399 {
00400
00401 assert( parsedLine.count() >= 10 );
00402 QStringList::const_iterator it = parsedLine.begin();
00403 ++it;
00404 mFlags = (*it++).toInt();
00405 mLevel = (*it++).toInt();
00406 mDescription = (*it++);
00407 bool ok;
00408
00409 mRealArgType = (*it++).toInt();
00410 mArgType = knownArgType( mRealArgType, ok );
00411 if ( !ok && !(*it).isEmpty() ) {
00412
00413 mRealArgType = (*it).toInt();
00414 mArgType = knownArgType( mRealArgType, ok );
00415 }
00416 if ( !ok )
00417 kdWarning(5150) << "Unsupported datatype: " << parsedLine[4] << " : " << *it << " for " << parsedLine[0] << endl;
00418 ++it;
00419 ++it;
00420
00421 mSet = false;
00422 QString value;
00423 if ( mFlags & GPGCONF_FLAG_DEFAULT ) {
00424 value = *it;
00425 mDefaultValue = stringToValue( value, true );
00426 }
00427 ++it;
00428 ++it;
00429
00430
00431 if ( !(*it).isEmpty() ) {
00432 mSet = true;
00433 value = *it;
00434 mValue = stringToValue( value, true );
00435 }
00436 else {
00437 mValue = mDefaultValue;
00438 }
00439
00440 mDirty = false;
00441 }
00442
00443 QVariant QGpgMECryptoConfigEntry::stringToValue( const QString& str, bool unescape ) const
00444 {
00445 bool isString = isStringType();
00446
00447 if ( isList() ) {
00448 QValueList<QVariant> lst;
00449 QStringList items = QStringList::split( ',', str );
00450 for( QStringList::const_iterator valit = items.begin(); valit != items.end(); ++valit ) {
00451 QString val = *valit;
00452 if ( isString ) {
00453 if ( val.isEmpty() ) {
00454 lst << QString::null;
00455 continue;
00456 }
00457 else if ( unescape ) {
00458 if( val[0] != '"' )
00459 kdWarning(5150) << "String value should start with '\"' : " << val << endl;
00460 val = val.mid( 1 );
00461 }
00462 }
00463 lst << QVariant( unescape ? gpgconf_unescape( val ) : val );
00464 }
00465 return lst;
00466 } else {
00467 QString val( str );
00468 if ( isString ) {
00469 if ( val.isEmpty() )
00470 return QVariant( QString::null );
00471 else if ( unescape ) {
00472 Q_ASSERT( val[0] == '"' );
00473 val = val.mid( 1 );
00474 }
00475 }
00476 return QVariant( unescape ? gpgconf_unescape( val ) : val );
00477 }
00478 }
00479
00480 QGpgMECryptoConfigEntry::~QGpgMECryptoConfigEntry()
00481 {
00482 #ifndef NDEBUG
00483 if ( !s_duringClear && mDirty )
00484 kdWarning(5150) << "Deleting a QGpgMECryptoConfigEntry that was modified (" << mDescription << ")\n"
00485 << "You forgot to call sync() (to commit) or clear() (to discard)" << endl;
00486 #endif
00487 }
00488
00489 bool QGpgMECryptoConfigEntry::isOptional() const
00490 {
00491 return mFlags & GPGCONF_FLAG_OPTIONAL;
00492 }
00493
00494 bool QGpgMECryptoConfigEntry::isList() const
00495 {
00496 return mFlags & GPGCONF_FLAG_LIST;
00497 }
00498
00499 bool QGpgMECryptoConfigEntry::isRuntime() const
00500 {
00501 return mFlags & GPGCONF_FLAG_RUNTIME;
00502 }
00503
00504 bool QGpgMECryptoConfigEntry::isSet() const
00505 {
00506 return mSet;
00507 }
00508
00509 bool QGpgMECryptoConfigEntry::boolValue() const
00510 {
00511 Q_ASSERT( mArgType == ArgType_None );
00512 Q_ASSERT( !isList() );
00513 return mValue.toBool();
00514 }
00515
00516 QString QGpgMECryptoConfigEntry::stringValue() const
00517 {
00518 return toString( false );
00519 }
00520
00521 int QGpgMECryptoConfigEntry::intValue() const
00522 {
00523 Q_ASSERT( mArgType == ArgType_Int );
00524 Q_ASSERT( !isList() );
00525 return mValue.toInt();
00526 }
00527
00528 unsigned int QGpgMECryptoConfigEntry::uintValue() const
00529 {
00530 Q_ASSERT( mArgType == ArgType_UInt );
00531 Q_ASSERT( !isList() );
00532 return mValue.toUInt();
00533 }
00534
00535 static KURL parseURL( int mRealArgType, const QString& str )
00536 {
00537 if ( mRealArgType == 33 ) {
00538
00539 QStringList items = QStringList::split( ':', str, true );
00540 if ( items.count() == 5 ) {
00541 QStringList::const_iterator it = items.begin();
00542 KURL url;
00543 url.setProtocol( "ldap" );
00544 url.setHost( urlpart_decode( *it++ ) );
00545 url.setPort( (*it++).toInt() );
00546 url.setPath( "/" );
00547 url.setUser( urlpart_decode( *it++ ) );
00548 url.setPass( urlpart_decode( *it++ ) );
00549 url.setQuery( urlpart_decode( *it ) );
00550 return url;
00551 } else
00552 kdWarning(5150) << "parseURL: malformed LDAP server: " << str << endl;
00553 }
00554
00555 return KURL( str );
00556 }
00557
00558
00559 static QString splitURL( int mRealArgType, const KURL& url )
00560 {
00561 if ( mRealArgType == 33 ) {
00562
00563 Q_ASSERT( url.protocol() == "ldap" );
00564 return urlpart_encode( url.host() ) + ":" +
00565 QString::number( url.port() ) + ":" +
00566 urlpart_encode( url.user() ) + ":" +
00567 urlpart_encode( url.pass() ) + ":" +
00568
00569
00570 urlpart_encode( KURL::decode_string( url.query().mid(1) ) );
00571 }
00572 return url.path();
00573 }
00574
00575 KURL QGpgMECryptoConfigEntry::urlValue() const
00576 {
00577 Q_ASSERT( mArgType == ArgType_Path || mArgType == ArgType_URL || mArgType == ArgType_LDAPURL );
00578 Q_ASSERT( !isList() );
00579 QString str = mValue.toString();
00580 if ( mArgType == ArgType_Path )
00581 {
00582 KURL url;
00583 url.setPath( str );
00584 return url;
00585 }
00586 return parseURL( mRealArgType, str );
00587 }
00588
00589 unsigned int QGpgMECryptoConfigEntry::numberOfTimesSet() const
00590 {
00591 Q_ASSERT( mArgType == ArgType_None );
00592 Q_ASSERT( isList() );
00593 return mValue.toUInt();
00594 }
00595
00596 QStringList QGpgMECryptoConfigEntry::stringValueList() const
00597 {
00598 Q_ASSERT( isStringType() );
00599 Q_ASSERT( isList() );
00600 return mValue.toStringList();
00601 }
00602
00603 QValueList<int> QGpgMECryptoConfigEntry::intValueList() const
00604 {
00605 Q_ASSERT( mArgType == ArgType_Int );
00606 Q_ASSERT( isList() );
00607 QValueList<int> ret;
00608 QValueList<QVariant> lst = mValue.toList();
00609 for( QValueList<QVariant>::const_iterator it = lst.begin(); it != lst.end(); ++it ) {
00610 ret.append( (*it).toInt() );
00611 }
00612 return ret;
00613 }
00614
00615 QValueList<unsigned int> QGpgMECryptoConfigEntry::uintValueList() const
00616 {
00617 Q_ASSERT( mArgType == ArgType_UInt );
00618 Q_ASSERT( isList() );
00619 QValueList<unsigned int> ret;
00620 QValueList<QVariant> lst = mValue.toList();
00621 for( QValueList<QVariant>::const_iterator it = lst.begin(); it != lst.end(); ++it ) {
00622 ret.append( (*it).toUInt() );
00623 }
00624 return ret;
00625 }
00626
00627 KURL::List QGpgMECryptoConfigEntry::urlValueList() const
00628 {
00629 Q_ASSERT( mArgType == ArgType_Path || mArgType == ArgType_URL || mArgType == ArgType_LDAPURL );
00630 Q_ASSERT( isList() );
00631 QStringList lst = mValue.toStringList();
00632
00633 KURL::List ret;
00634 for( QStringList::const_iterator it = lst.begin(); it != lst.end(); ++it ) {
00635 if ( mArgType == ArgType_Path ) {
00636 KURL url;
00637 url.setPath( *it );
00638 ret << url;
00639 } else {
00640 ret << parseURL( mRealArgType, *it );
00641 }
00642 }
00643 return ret;
00644 }
00645
00646 void QGpgMECryptoConfigEntry::resetToDefault()
00647 {
00648 mSet = false;
00649 mDirty = true;
00650 if ( mFlags & GPGCONF_FLAG_DEFAULT )
00651 mValue = mDefaultValue;
00652 else if ( mArgType == ArgType_None )
00653 mValue = false;
00654 }
00655
00656 void QGpgMECryptoConfigEntry::setBoolValue( bool b )
00657 {
00658 Q_ASSERT( mArgType == ArgType_None );
00659 Q_ASSERT( !isList() );
00660
00661
00662 mValue = b;
00663 mSet = b;
00664 mDirty = true;
00665 }
00666
00667 void QGpgMECryptoConfigEntry::setStringValue( const QString& str )
00668 {
00669 mValue = stringToValue( str, false );
00670
00671
00672
00673 if ( str.isEmpty() && !isOptional() )
00674 mSet = false;
00675 else
00676 mSet = true;
00677 mDirty = true;
00678 }
00679
00680 void QGpgMECryptoConfigEntry::setIntValue( int i )
00681 {
00682 Q_ASSERT( mArgType == ArgType_Int );
00683 Q_ASSERT( !isList() );
00684 mValue = i;
00685 mSet = true;
00686 mDirty = true;
00687 }
00688
00689 void QGpgMECryptoConfigEntry::setUIntValue( unsigned int i )
00690 {
00691 mValue = i;
00692 mSet = true;
00693 mDirty = true;
00694 }
00695
00696 void QGpgMECryptoConfigEntry::setURLValue( const KURL& url )
00697 {
00698 QString str = splitURL( mRealArgType, url );
00699 if ( str.isEmpty() && !isOptional() )
00700 mSet = false;
00701 else
00702 mSet = true;
00703 mValue = str;
00704 mDirty = true;
00705 }
00706
00707 void QGpgMECryptoConfigEntry::setNumberOfTimesSet( unsigned int i )
00708 {
00709 Q_ASSERT( mArgType == ArgType_None );
00710 Q_ASSERT( isList() );
00711 setUIntValue( i );
00712 }
00713
00714 void QGpgMECryptoConfigEntry::setStringValueList( const QStringList& lst )
00715 {
00716 mValue = lst;
00717 if ( lst.isEmpty() && !isOptional() )
00718 mSet = false;
00719 else
00720 mSet = true;
00721 mDirty = true;
00722 }
00723
00724 void QGpgMECryptoConfigEntry::setIntValueList( const QValueList<int>& lst )
00725 {
00726 QValueList<QVariant> ret;
00727 for( QValueList<int>::const_iterator it = lst.begin(); it != lst.end(); ++it ) {
00728 ret << QVariant( *it );
00729 }
00730 mValue = ret;
00731 if ( ret.isEmpty() && !isOptional() )
00732 mSet = false;
00733 else
00734 mSet = true;
00735 mDirty = true;
00736 }
00737
00738 void QGpgMECryptoConfigEntry::setUIntValueList( const QValueList<unsigned int>& lst )
00739 {
00740 QValueList<QVariant> ret;
00741 for( QValueList<unsigned int>::const_iterator it = lst.begin(); it != lst.end(); ++it ) {
00742 ret << QVariant( *it );
00743 }
00744 if ( ret.isEmpty() && !isOptional() )
00745 mSet = false;
00746 else
00747 mSet = true;
00748 mValue = ret;
00749 mDirty = true;
00750 }
00751
00752 void QGpgMECryptoConfigEntry::setURLValueList( const KURL::List& urls )
00753 {
00754 QStringList lst;
00755 for( KURL::List::const_iterator it = urls.begin(); it != urls.end(); ++it ) {
00756 lst << splitURL( mRealArgType, *it );
00757 }
00758 mValue = lst;
00759 if ( lst.isEmpty() && !isOptional() )
00760 mSet = false;
00761 else
00762 mSet = true;
00763 mDirty = true;
00764 }
00765
00766 QString QGpgMECryptoConfigEntry::toString( bool escape ) const
00767 {
00768
00769 if ( isStringType() ) {
00770 if ( mValue.isNull() )
00771 return QString::null;
00772 else if ( isList() ) {
00773 QStringList lst = mValue.toStringList();
00774 if ( escape ) {
00775 for( QStringList::iterator it = lst.begin(); it != lst.end(); ++it ) {
00776 if ( !(*it).isNull() )
00777 *it = gpgconf_escape( *it ).prepend( "\"" );
00778 }
00779 }
00780 QString res = lst.join( "," );
00781 kdDebug(5150) << "toString: " << res << endl;
00782 return res;
00783 } else {
00784 QString res = mValue.toString();
00785 if ( escape )
00786 res = gpgconf_escape( res ).prepend( "\"" );
00787 return res;
00788 }
00789 }
00790 if ( !isList() )
00791 {
00792 if ( mArgType == ArgType_None ) {
00793 return mValue.toBool() ? QString::fromLatin1( "1" ) : QString::null;
00794 } else {
00795 Q_ASSERT( mArgType == ArgType_Int || mArgType == ArgType_UInt );
00796 return mValue.toString();
00797 }
00798 }
00799
00800
00801 if ( mArgType == ArgType_None )
00802 return QString::number( numberOfTimesSet() );
00803 QStringList ret;
00804 QValueList<QVariant> lst = mValue.toList();
00805 for( QValueList<QVariant>::const_iterator it = lst.begin(); it != lst.end(); ++it ) {
00806 ret << (*it).toString();
00807 }
00808 return ret.join( "," );
00809 }
00810
00811 QString QGpgMECryptoConfigEntry::outputString() const
00812 {
00813 Q_ASSERT( mSet );
00814 return toString( true );
00815 }
00816
00817 bool QGpgMECryptoConfigEntry::isStringType() const
00818 {
00819 return ( mArgType == Kleo::CryptoConfigEntry::ArgType_String
00820 || mArgType == Kleo::CryptoConfigEntry::ArgType_Path
00821 || mArgType == Kleo::CryptoConfigEntry::ArgType_URL
00822 || mArgType == Kleo::CryptoConfigEntry::ArgType_LDAPURL );
00823 }
00824
00825 void QGpgMECryptoConfigEntry::setDirty( bool b )
00826 {
00827 mDirty = b;
00828 }
00829
00830 #include "qgpgmecryptoconfig.moc"