From ee6483a76e62a69641530f36ad35f1f686914442 Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Mon, 19 Apr 2010 15:38:02 +1000 Subject: move network scan to thread. increases startup time. Task-number: QTBUG-9722 --- src/plugins/bearer/corewlan/qcorewlanengine.h | 41 +- src/plugins/bearer/corewlan/qcorewlanengine.mm | 819 +++++++++++++------------ 2 files changed, 464 insertions(+), 396 deletions(-) diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.h b/src/plugins/bearer/corewlan/qcorewlanengine.h index 5c69299..854dcea 100644 --- a/src/plugins/bearer/corewlan/qcorewlanengine.h +++ b/src/plugins/bearer/corewlan/qcorewlanengine.h @@ -47,15 +47,18 @@ #include #include #include +#include #ifndef QT_NO_BEARERMANAGEMENT QT_BEGIN_NAMESPACE class QNetworkConfigurationPrivate; +class QScanThread; class QCoreWlanEngine : public QBearerEngineImpl { + friend class QScanThread; Q_OBJECT public: @@ -83,28 +86,54 @@ public: bool requiresPolling() const; private Q_SLOTS: + void init(); void doRequestUpdate(); + void networksChanged(); private: bool isWifiReady(const QString &dev); - QMap configurationInterface; - QStringList scanForSsids(const QString &interfaceName); - - bool isKnownSsid(const QString &ssid); QList foundConfigurations; SCDynamicStoreRef storeSession; CFRunLoopSourceRef runloopSource; bool hasWifi; + bool scanning; + QScanThread *scanThread; protected: - QMap > userProfiles; - void startNetworkChangeLoop(); + +}; + +class QScanThread : public QThread +{ + Q_OBJECT + +public: + QScanThread(QObject *parent = 0); + ~QScanThread(); + + void quit(); + QList getConfigurations(); + QString interfaceName; + QMap configurationInterface; void getUserConfigurations(); QString getNetworkNameFromSsid(const QString &ssid); QString getSsidFromNetworkName(const QString &name); + bool isKnownSsid(const QString &ssid); + QMap > userProfiles; + +signals: + void networksChanged(); + +protected: + void run(); + +private: + QList fetchedConfigurations; + QMutex mutex; QStringList foundNetwork(const QString &id, const QString &ssid, const QNetworkConfiguration::StateFlags state, const QString &interfaceName, const QNetworkConfiguration::Purpose purpose); + }; QT_END_NAMESPACE diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm index 268126a..f54bd4d 100644 --- a/src/plugins/bearer/corewlan/qcorewlanengine.mm +++ b/src/plugins/bearer/corewlan/qcorewlanengine.mm @@ -67,10 +67,6 @@ #include #include "private/qcore_mac_p.h" -#ifndef QT_NO_BEARERMANAGEMENT - -QT_BEGIN_NAMESPACE - @interface QNSListener : NSObject { NSNotificationCenter *center; @@ -96,7 +92,6 @@ QT_BEGIN_NAMESPACE QMacCocoaAutoReleasePool pool; center = [NSNotificationCenter defaultCenter]; currentInterface = [CWInterface interfaceWithName:nil]; -// [center addObserver:self selector:@selector(notificationHandler:) name:kCWLinkDidChangeNotification object:nil]; [center addObserver:self selector:@selector(notificationHandler:) name:kCWPowerDidChangeNotification object:nil]; [locker unlock]; return self; @@ -130,6 +125,8 @@ QT_BEGIN_NAMESPACE QNSListener *listener = 0; +QT_BEGIN_NAMESPACE + void networkChangeCallback(SCDynamicStoreRef/* store*/, CFArrayRef changedKeys, void *info) { for ( long i = 0; i < CFArrayGetCount(changedKeys); i++) { @@ -143,20 +140,277 @@ void networkChangeCallback(SCDynamicStoreRef/* store*/, CFArrayRef changedKeys, return; } -QCoreWlanEngine::QCoreWlanEngine(QObject *parent) -: QBearerEngineImpl(parent) + +QScanThread::QScanThread(QObject *parent) + :QThread(parent) { - startNetworkChangeLoop(); +} + +QScanThread::~QScanThread() +{ +} + +void QScanThread::quit() +{ + wait(); +} + +void QScanThread::run() +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + QStringList found; + mutex.lock(); + CWInterface *currentInterface = [CWInterface interfaceWithName:qt_mac_QStringToNSString(interfaceName)]; + mutex.unlock(); + + if([currentInterface power]) { + NSError *err = nil; + NSDictionary *parametersDict = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:YES], kCWScanKeyMerge, + [NSNumber numberWithInteger:100], kCWScanKeyRestTime, nil]; + + NSArray* apArray = [currentInterface scanForNetworksWithParameters:parametersDict error:&err]; + CWNetwork *apNetwork; + + if (!err) { + + for(uint row=0; row < [apArray count]; row++ ) { + apNetwork = [apArray objectAtIndex:row]; + + const QString networkSsid = qt_mac_NSStringToQString([apNetwork ssid]); + const QString id = QString::number(qHash(QLatin1String("corewlan:") + networkSsid)); + found.append(id); + + QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined; + bool known = isKnownSsid(networkSsid); + if( [currentInterface.interfaceState intValue] == kCWInterfaceStateRunning) { + if( networkSsid == qt_mac_NSStringToQString( [currentInterface ssid])) { + state = QNetworkConfiguration::Active; + } + } + if(state == QNetworkConfiguration::Undefined) { + if(known) { + state = QNetworkConfiguration::Discovered; + } else { + state = QNetworkConfiguration::Undefined; + } + } + QNetworkConfiguration::Purpose purpose = QNetworkConfiguration::UnknownPurpose; + if([[apNetwork securityMode] intValue] == kCWSecurityModeOpen) { + purpose = QNetworkConfiguration::PublicPurpose; + } else { + purpose = QNetworkConfiguration::PrivatePurpose; + } + + found.append(foundNetwork(id, networkSsid, state, interfaceName, purpose)); + + } //end row +// [parametersDict release]; + + } //end error + } // endwifi power + // add known configurations that are not around. + QMapIterator > i(userProfiles); + while (i.hasNext()) { + i.next(); + + QString networkName = i.key(); + const QString id = QString::number(qHash(QLatin1String("corewlan:") + networkName)); + + if(!found.contains(id)) { + QString networkSsid = getSsidFromNetworkName(networkName); + const QString ssidId = QString::number(qHash(QLatin1String("corewlan:") + networkSsid)); + QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined; + QString interfaceName; + QMapIterator ij(i.value()); + while (ij.hasNext()) { + ij.next(); + interfaceName = ij.value(); + } + + if( [currentInterface.interfaceState intValue] == kCWInterfaceStateRunning) { + if( networkSsid == qt_mac_NSStringToQString([currentInterface ssid])) { + state = QNetworkConfiguration::Active; + } + } + if(state == QNetworkConfiguration::Undefined) { + if( userProfiles.contains(networkName) + && found.contains(ssidId)) { + state = QNetworkConfiguration::Discovered; + } + } + + if(state == QNetworkConfiguration::Undefined) { + state = QNetworkConfiguration::Defined; + } + + found.append(foundNetwork(id, networkName, state, interfaceName, QNetworkConfiguration::UnknownPurpose)); + } + } + emit networksChanged(); + [pool release]; +} + +QStringList QScanThread::foundNetwork(const QString &id, const QString &name, const QNetworkConfiguration::StateFlags state, const QString &interfaceName, const QNetworkConfiguration::Purpose purpose) +{ + QStringList found; + QMutexLocker locker(&mutex); + QNetworkConfigurationPrivate *ptr = new QNetworkConfigurationPrivate; + ptr->name = name; + ptr->isValid = true; + ptr->id = id; + ptr->state = state; + ptr->type = QNetworkConfiguration::InternetAccessPoint; + ptr->bearer = QLatin1String("WLAN"); + ptr->purpose = purpose; + + fetchedConfigurations.append( ptr); + configurationInterface.insert(ptr->id, interfaceName); + + locker.unlock(); + locker.relock(); + found.append(id); + return found; +} + +QList QScanThread::getConfigurations() +{ + QMutexLocker locker(&mutex); + + QList foundConfigurations = fetchedConfigurations; + fetchedConfigurations.clear(); + + return foundConfigurations; +} + +void QScanThread::getUserConfigurations() +{ QMacCocoaAutoReleasePool pool; - if([[CWInterface supportedInterfaces] count] > 0 && !listener) { - listener = [[QNSListener alloc] init]; - listener.engine = this; - hasWifi = true; - } else { - hasWifi = false; + userProfiles.clear(); + + NSArray *wifiInterfaces = [CWInterface supportedInterfaces]; + for(uint row=0; row < [wifiInterfaces count]; row++ ) { + + CWInterface *wifiInterface = [CWInterface interfaceWithName: [wifiInterfaces objectAtIndex:row]]; + NSString *nsInterfaceName = [wifiInterface name]; +// add user configured system networks + SCDynamicStoreRef dynRef = SCDynamicStoreCreate(kCFAllocatorSystemDefault, (CFStringRef)@"Qt corewlan", nil, nil); + NSDictionary * airportPlist = (NSDictionary *)SCDynamicStoreCopyValue(dynRef, (CFStringRef)[NSString stringWithFormat:@"Setup:/Network/Interface/%@/AirPort", nsInterfaceName]); + CFRelease(dynRef); + + NSDictionary *prefNetDict = [airportPlist objectForKey:@"PreferredNetworks"]; + + NSArray *thisSsidarray = [prefNetDict valueForKey:@"SSID_STR"]; + for(NSString *ssidkey in thisSsidarray) { + QString thisSsid = qt_mac_NSStringToQString(ssidkey); + if(!userProfiles.contains(thisSsid)) { + QMap map; + map.insert(thisSsid, qt_mac_NSStringToQString(nsInterfaceName)); + userProfiles.insert(thisSsid, map); + } + } + CFRelease(airportPlist); + + // 802.1X user profiles + QString userProfilePath = QDir::homePath() + "/Library/Preferences/com.apple.eap.profiles.plist"; + NSDictionary* eapDict = [[NSMutableDictionary alloc] initWithContentsOfFile:qt_mac_QStringToNSString(userProfilePath)]; + NSString *profileStr= @"Profiles"; + NSString *nameStr = @"UserDefinedName"; + NSString *networkSsidStr = @"Wireless Network"; + for (id profileKey in eapDict) { + if ([profileStr isEqualToString:profileKey]) { + NSDictionary *itemDict = [eapDict objectForKey:profileKey]; + for (id itemKey in itemDict) { + + NSInteger dictSize = [itemKey count]; + id objects[dictSize]; + id keys[dictSize]; + + [itemKey getObjects:objects andKeys:keys]; + QString networkName; + QString ssid; + for(int i = 0; i < dictSize; i++) { + if([nameStr isEqualToString:keys[i]]) { + networkName = qt_mac_NSStringToQString(objects[i]); + } + if([networkSsidStr isEqualToString:keys[i]]) { + ssid = qt_mac_NSStringToQString(objects[i]); + } + if(!userProfiles.contains(networkName) + && !ssid.isEmpty()) { + QMap map; + map.insert(ssid, qt_mac_NSStringToQString(nsInterfaceName)); + userProfiles.insert(networkName, map); + } + } + } + [itemDict release]; + } + } + [eapDict release]; + } +} + +QString QScanThread::getSsidFromNetworkName(const QString &name) +{ + QMapIterator > i(userProfiles); + while (i.hasNext()) { + i.next(); + QMap map = i.value(); + QMapIterator ij(i.value()); + while (ij.hasNext()) { + ij.next(); + const QString networkNameHash = QString::number(qHash(QLatin1String("corewlan:") +i.key())); + if(name == i.key() || name == networkNameHash) { + return ij.key(); + } + } + } + return QString(); +} + +QString QScanThread::getNetworkNameFromSsid(const QString &ssid) +{ + QMapIterator > i(userProfiles); + while (i.hasNext()) { + i.next(); + QMap map = i.value(); + QMapIterator ij(i.value()); + while (ij.hasNext()) { + ij.next(); + if(ij.key() == ssid) { + return i.key(); + } + } } - QMetaObject::invokeMethod(this, "requestUpdate", Qt::QueuedConnection); + return QString(); +} + +bool QScanThread::isKnownSsid(const QString &ssid) +{ + QMutexLocker locker(&mutex); + + QMapIterator > i(userProfiles); + while (i.hasNext()) { + i.next(); + QMap map = i.value(); + if(map.keys().contains(ssid)) { + return true; + } + } + return false; +} + + +QCoreWlanEngine::QCoreWlanEngine(QObject *parent) +: QBearerEngineImpl(parent), scanThread(0) +{ + scanThread = new QScanThread(this); + connect(scanThread, SIGNAL(networksChanged()), + this, SLOT(networksChanged())); + + QTimer::singleShot(0,this,SLOT(init())); } QCoreWlanEngine::~QCoreWlanEngine() @@ -167,18 +421,33 @@ QCoreWlanEngine::~QCoreWlanEngine() [listener release]; } +void QCoreWlanEngine::init() +{ + if([[CWInterface supportedInterfaces] count] > 0 && !listener) { + listener = [[QNSListener alloc] init]; + listener.engine = this; + hasWifi = true; + } else { + hasWifi = false; + } + storeSession = NULL; + + startNetworkChangeLoop(); +} + + QString QCoreWlanEngine::getInterfaceFromId(const QString &id) { QMutexLocker locker(&mutex); - return configurationInterface.value(id); + return scanThread->configurationInterface.value(id); } bool QCoreWlanEngine::hasIdentifier(const QString &id) { QMutexLocker locker(&mutex); - return configurationInterface.contains(id); + return scanThread->configurationInterface.contains(id); } void QCoreWlanEngine::connectToId(const QString &id) @@ -195,13 +464,14 @@ void QCoreWlanEngine::connectToId(const QString &id) NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:0]; QString wantedSsid; - bool using8021X = false; QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); - const QString idHash = QString::number(qHash(QLatin1String("corewlan:") + getNetworkNameFromSsid(ptr->name))); + const QString idHash = QString::number(qHash(QLatin1String("corewlan:") + ptr->name)); + const QString idHash2 = QString::number(qHash(QLatin1String("corewlan:") + scanThread->getNetworkNameFromSsid(ptr->name))); - if (idHash != id) { + bool using8021X = false; + if (idHash2 != id) { NSArray *array = [CW8021XProfile allUser8021XProfiles]; for (NSUInteger i = 0; i < [array count]; ++i) { @@ -210,7 +480,7 @@ void QCoreWlanEngine::connectToId(const QString &id) const QString ssidHash = QString::number(qHash(QLatin1String("corewlan:") + qt_mac_NSStringToQString([[array objectAtIndex:i] ssid]))); if (id == networkNameHashCheck || id == ssidHash) { - const QString thisName = getSsidFromNetworkName(id); + const QString thisName = scanThread->getSsidFromNetworkName(id); if (thisName.isEmpty()) wantedSsid = id; else @@ -225,24 +495,25 @@ void QCoreWlanEngine::connectToId(const QString &id) if (!using8021X) { QString wantedNetwork; - QMapIterator > i(userProfiles); + QMapIterator > i(scanThread->userProfiles); while (i.hasNext()) { i.next(); wantedNetwork = i.key(); const QString networkNameHash = QString::number(qHash(QLatin1String("corewlan:") + wantedNetwork)); if (id == networkNameHash) { - wantedSsid = getSsidFromNetworkName(wantedNetwork); + wantedSsid = scanThread->getSsidFromNetworkName(wantedNetwork); break; } } } NSDictionary *scanParameters = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], kCWScanKeyMerge, + [NSNumber numberWithInt:kCWScanTypeFast], kCWScanKeyScanType, [NSNumber numberWithInteger:100], kCWScanKeyRestTime, qt_mac_QStringToNSString(wantedSsid), kCWScanKeySSID, nil]; - NSArray *scanArray = [NSArray arrayWithArray:[wifiInterface scanForNetworksWithParameters:scanParameters error:&err]]; + NSArray *scanArray = [wifiInterface scanForNetworksWithParameters:scanParameters error:&err]; if(!err) { for(uint row=0; row < [scanArray count]; row++ ) { @@ -261,326 +532,110 @@ void QCoreWlanEngine::connectToId(const QString &id) attributes[0].data = (void *)[account UTF8String]; attributes[0].length = [account length]; - attributes[1].tag = kSecDescriptionItemAttr; - attributes[1].data = (void *)[keyKind UTF8String]; - attributes[1].length = [keyKind length]; - - attributes[2].tag = kSecLabelItemAttr; - attributes[2].data = (void *)[keyName UTF8String]; - attributes[2].length = [keyName length]; - - SecKeychainAttributeList attributeList = {3,attributes}; - - SecKeychainSearchRef searchRef; - SecKeychainSearchCreateFromAttributes(NULL, kSecGenericPasswordItemClass, &attributeList, &searchRef); - - NSString *password = @""; - SecKeychainItemRef searchItem; - - if (SecKeychainSearchCopyNext(searchRef, &searchItem) == noErr) { - UInt32 realPasswordLength; - SecKeychainAttribute attributesW[8]; - attributesW[0].tag = kSecAccountItemAttr; - SecKeychainAttributeList listW = {1,attributesW}; - char *realPassword; - OSStatus status = SecKeychainItemCopyContent(searchItem, NULL, &listW, &realPasswordLength,(void **)&realPassword); - - if (status == noErr) { - if (realPassword != NULL) { - - QByteArray pBuf; - pBuf.resize(realPasswordLength); - pBuf.prepend(realPassword); - pBuf.insert(realPasswordLength,'\0'); - - password = [NSString stringWithUTF8String:pBuf]; - } - SecKeychainItemFreeContent(&listW, realPassword); - } - - CFRelease(searchItem); - } else { - qDebug() << "SecKeychainSearchCopyNext error"; - } - [params setValue: password forKey: kCWAssocKeyPassphrase]; - } // end using8021X - - - bool result = [wifiInterface associateToNetwork: apNetwork parameters:[NSDictionary dictionaryWithDictionary:params] error:&err]; - - if(!err) { - if(!result) { - emit connectionError(id, ConnectError); - } else { - return; - } - } else { - qDebug() <<"associate ERROR"<< qt_mac_NSStringToQString([err localizedDescription ]); - } - } - } //end scan network - } else { - qDebug() <<"scan ERROR"<< qt_mac_NSStringToQString([err localizedDescription ]); - } - emit connectionError(id, InterfaceLookupError); - } - - locker.unlock(); - emit connectionError(id, InterfaceLookupError); -} - -void QCoreWlanEngine::disconnectFromId(const QString &id) -{ - QMutexLocker locker(&mutex); - - QString interfaceString = getInterfaceFromId(id); - QMacCocoaAutoReleasePool pool; - - CWInterface *wifiInterface = - [CWInterface interfaceWithName: qt_mac_QStringToNSString(interfaceString)]; - - [wifiInterface disassociate]; - if ([[wifiInterface interfaceState]intValue] != kCWInterfaceStateInactive) { - locker.unlock(); - emit connectionError(id, DisconnectionError); - locker.relock(); - } -} - -void QCoreWlanEngine::requestUpdate() -{ - getUserConfigurations(); - doRequestUpdate(); -} - -void QCoreWlanEngine::doRequestUpdate() -{ - QMutexLocker locker(&mutex); - - QMacCocoaAutoReleasePool pool; - - QStringList previous = accessPointConfigurations.keys(); - - NSArray *wifiInterfaces = [CWInterface supportedInterfaces]; - for (uint row = 0; row < [wifiInterfaces count]; ++row) { - foreach (const QString &interface, - scanForSsids(qt_mac_NSStringToQString([wifiInterfaces objectAtIndex:row]))) { - previous.removeAll(interface); - } - } - - while (!previous.isEmpty()) { - QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(previous.takeFirst()); - - configurationInterface.remove(ptr->id); - - locker.unlock(); - emit configurationRemoved(ptr); - locker.relock(); - } - - locker.unlock(); - emit updateCompleted(); -} - -QString QCoreWlanEngine::getSsidFromNetworkName(const QString &name) -{ - QMapIterator > i(userProfiles); - while (i.hasNext()) { - i.next(); - QMap map = i.value(); - QMapIterator ij(i.value()); - while (ij.hasNext()) { - ij.next(); - const QString networkNameHash = QString::number(qHash(QLatin1String("corewlan:") + i.key())); - if (name == i.key() || name == networkNameHash) { - return ij.key(); - } - } - } - return QString(); -} - -QString QCoreWlanEngine::getNetworkNameFromSsid(const QString &ssid) -{ - QMapIterator > i(userProfiles); - while (i.hasNext()) { - i.next(); - QMap map = i.value(); - QMapIterator ij(i.value()); - while (ij.hasNext()) { - ij.next(); - if(ij.key() == ssid) { - return i.key(); - } - } - } - return QString(); -} - -QStringList QCoreWlanEngine::scanForSsids(const QString &interfaceName) -{ - QMutexLocker locker(&mutex); - - QStringList found; - - if(!hasWifi) { - return found; - } - QMacCocoaAutoReleasePool pool; - - CWInterface *currentInterface = [CWInterface interfaceWithName:qt_mac_QStringToNSString(interfaceName)]; - QStringList addedConfigs; - - if([currentInterface power]) { - NSError *err = nil; - NSDictionary *parametersDict = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithBool:YES], kCWScanKeyMerge, - [NSNumber numberWithInt:kCWScanTypeFast], kCWScanKeyScanType, // get the networks in the scan cache - [NSNumber numberWithInteger:100], kCWScanKeyRestTime, nil]; - NSArray* apArray = [currentInterface scanForNetworksWithParameters:parametersDict error:&err]; - CWNetwork *apNetwork; - if (!err) { - - for(uint row=0; row < [apArray count]; row++ ) { - apNetwork = [apArray objectAtIndex:row]; + attributes[1].tag = kSecDescriptionItemAttr; + attributes[1].data = (void *)[keyKind UTF8String]; + attributes[1].length = [keyKind length]; - const QString networkSsid = qt_mac_NSStringToQString([apNetwork ssid]); + attributes[2].tag = kSecLabelItemAttr; + attributes[2].data = (void *)[keyName UTF8String]; + attributes[2].length = [keyName length]; - const QString id = QString::number(qHash(QLatin1String("corewlan:") + networkSsid)); - found.append(id); + SecKeychainAttributeList attributeList = {3,attributes}; - QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined; - bool known = isKnownSsid(networkSsid); - if( [currentInterface.interfaceState intValue] == kCWInterfaceStateRunning) { - if( networkSsid == qt_mac_NSStringToQString( [currentInterface ssid])) { - state = QNetworkConfiguration::Active; - } - } - if(state == QNetworkConfiguration::Undefined) { - if(known) { - state = QNetworkConfiguration::Discovered; - } else { - state = QNetworkConfiguration::Undefined; - } - } - QNetworkConfiguration::Purpose purpose = QNetworkConfiguration::UnknownPurpose; - if([[apNetwork securityMode] intValue] == kCWSecurityModeOpen) { - purpose = QNetworkConfiguration::PublicPurpose; - } else { - purpose = QNetworkConfiguration::PrivatePurpose; - } + SecKeychainSearchRef searchRef; + SecKeychainSearchCreateFromAttributes(NULL, kSecGenericPasswordItemClass, &attributeList, &searchRef); - found.append(foundNetwork(id, networkSsid, state, interfaceName, purpose)); + NSString *password = @""; + SecKeychainItemRef searchItem; - } //end row - } //end error - } // endwifi power + if (SecKeychainSearchCopyNext(searchRef, &searchItem) == noErr) { + UInt32 realPasswordLength; + SecKeychainAttribute attributesW[8]; + attributesW[0].tag = kSecAccountItemAttr; + SecKeychainAttributeList listW = {1,attributesW}; + char *realPassword; + OSStatus status = SecKeychainItemCopyContent(searchItem, NULL, &listW, &realPasswordLength,(void **)&realPassword); - // add known configurations that are not around. - QMapIterator > i(userProfiles); - while (i.hasNext()) { - i.next(); + if (status == noErr) { + if (realPassword != NULL) { - QString networkName = i.key(); - const QString id = QString::number(qHash(QLatin1String("corewlan:") + networkName)); + QByteArray pBuf; + pBuf.resize(realPasswordLength); + pBuf.prepend(realPassword); + pBuf.insert(realPasswordLength,'\0'); - if(!found.contains(id)) { - QString networkSsid = getSsidFromNetworkName(networkName); - const QString ssidId = QString::number(qHash(QLatin1String("corewlan:") + networkSsid)); - QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined; - QString interfaceName; - QMapIterator ij(i.value()); - while (ij.hasNext()) { - ij.next(); - interfaceName = ij.value(); - } + password = [NSString stringWithUTF8String:pBuf]; + } + SecKeychainItemFreeContent(&listW, realPassword); + } - if( [currentInterface.interfaceState intValue] == kCWInterfaceStateRunning) { - if( networkSsid == qt_mac_NSStringToQString([currentInterface ssid])) { - state = QNetworkConfiguration::Active; - } - } - if(state == QNetworkConfiguration::Undefined) { - if( userProfiles.contains(networkName) - && found.contains(ssidId)) { - state = QNetworkConfiguration::Discovered; - } - } + CFRelease(searchItem); + } else { + qDebug() << "SecKeychainSearchCopyNext error"; + } + [params setValue: password forKey: kCWAssocKeyPassphrase]; + } // end using8021X - if(state == QNetworkConfiguration::Undefined) { - state = QNetworkConfiguration::Defined; - } - found.append(foundNetwork(id, networkName, state, interfaceName, QNetworkConfiguration::UnknownPurpose)); + bool result = [wifiInterface associateToNetwork: apNetwork parameters:[NSDictionary dictionaryWithDictionary:params] error:&err]; + + if(!err) { + if(!result) { + emit connectionError(id, ConnectError); + } else { + return; + } + } else { + qDebug() <<"associate ERROR"<< qt_mac_NSStringToQString([err localizedDescription ]); + } + } + } //end scan network + } else { + qDebug() <<"scan ERROR"<< qt_mac_NSStringToQString([err localizedDescription ]); } + emit connectionError(id, InterfaceLookupError); } - return found; + + locker.unlock(); + emit connectionError(id, InterfaceLookupError); } -QStringList QCoreWlanEngine::foundNetwork(const QString &id, const QString &name, const QNetworkConfiguration::StateFlags state, const QString &interfaceName, const QNetworkConfiguration::Purpose purpose) +void QCoreWlanEngine::disconnectFromId(const QString &id) { - QStringList found; QMutexLocker locker(&mutex); - if (accessPointConfigurations.contains(id)) { - QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); - - bool changed = false; - - ptr->mutex.lock(); - - if (!ptr->isValid) { - ptr->isValid = true; - changed = true; - } - - if (ptr->name != name) { - ptr->name = name; - changed = true; - } - if (ptr->id != id) { - ptr->id = id; - changed = true; - } + QString interfaceString = getInterfaceFromId(id); + QMacCocoaAutoReleasePool pool; - if (ptr->state != state) { - ptr->state = state; - changed = true; - } + CWInterface *wifiInterface = + [CWInterface interfaceWithName: qt_mac_QStringToNSString(interfaceString)]; - if (ptr->purpose != purpose) { - ptr->purpose = purpose; - changed = true; - } - ptr->mutex.unlock(); + [wifiInterface disassociate]; + if ([[wifiInterface interfaceState]intValue] != kCWInterfaceStateInactive) { + locker.unlock(); + emit connectionError(id, DisconnectionError); + locker.relock(); + } +} - if (changed) { - locker.unlock(); - emit configurationChanged(ptr); - locker.relock(); - } - found.append(id); - } else { - QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate); +void QCoreWlanEngine::requestUpdate() +{ + scanThread->getUserConfigurations(); + doRequestUpdate(); +} - ptr->name = name; - ptr->isValid = true; - ptr->id = id; - ptr->state = state; - ptr->type = QNetworkConfiguration::InternetAccessPoint; - ptr->bearer = QLatin1String("WLAN"); - ptr->purpose = purpose; +void QCoreWlanEngine::doRequestUpdate() +{ + QMutexLocker locker(&mutex); - accessPointConfigurations.insert(ptr->id, ptr); - configurationInterface.insert(ptr->id, interfaceName); + QMacCocoaAutoReleasePool pool; - locker.unlock(); - emit configurationAdded(ptr); - locker.relock(); - found.append(id); + NSArray *wifiInterfaces = [CWInterface supportedInterfaces]; + for (uint row = 0; row < [wifiInterfaces count]; ++row) { + scanThread->interfaceName = qt_mac_NSStringToQString([wifiInterfaces objectAtIndex:row]); + scanThread->start(); } - return found; + locker.unlock(); } bool QCoreWlanEngine::isWifiReady(const QString &wifiDeviceName) @@ -596,20 +651,6 @@ bool QCoreWlanEngine::isWifiReady(const QString &wifiDeviceName) return false; } -bool QCoreWlanEngine::isKnownSsid(const QString &ssid) -{ - QMutexLocker locker(&mutex); - - QMapIterator > i(userProfiles); - while (i.hasNext()) { - i.next(); - QMap map = i.value(); - if(map.keys().contains(ssid)) { - return true; - } - } - return false; -} QNetworkSession::State QCoreWlanEngine::sessionStateForId(const QString &id) { @@ -644,7 +685,6 @@ QNetworkConfigurationManager::Capabilities QCoreWlanEngine::capabilities() const void QCoreWlanEngine::startNetworkChangeLoop() { - storeSession = NULL; SCDynamicStoreContext dynStoreContext = { 0, this/*(void *)storeSession*/, NULL, NULL, NULL }; storeSession = SCDynamicStoreCreate(NULL, @@ -711,74 +751,73 @@ bool QCoreWlanEngine::requiresPolling() const return true; } -void QCoreWlanEngine::getUserConfigurations() +void QCoreWlanEngine::networksChanged() { - QMacCocoaAutoReleasePool pool; - userProfiles.clear(); + QMutexLocker locker(&mutex); - NSArray *wifiInterfaces = [CWInterface supportedInterfaces]; - for(uint row=0; row < [wifiInterfaces count]; row++ ) { + QStringList previous = accessPointConfigurations.keys(); - CWInterface *wifiInterface = [CWInterface interfaceWithName: [wifiInterfaces objectAtIndex:row]]; - NSString *nsInterfaceName = [wifiInterface name]; -// add user configured system networks - SCDynamicStoreRef dynRef = SCDynamicStoreCreate(kCFAllocatorSystemDefault, (CFStringRef)@"Qt corewlan", nil, nil); - NSDictionary *airportPlist = (NSDictionary *)SCDynamicStoreCopyValue(dynRef, (CFStringRef)[[NSString stringWithFormat:@"Setup:/Network/Interface/%@/AirPort", nsInterfaceName] autorelease]); - CFRelease(dynRef); + QList foundConfigurations = scanThread->getConfigurations(); + while (!foundConfigurations.isEmpty()) { + QNetworkConfigurationPrivate *cpPriv = foundConfigurations.takeFirst(); - NSDictionary *prefNetDict = [airportPlist objectForKey:@"PreferredNetworks"]; + previous.removeAll(cpPriv->id); - NSArray *thisSsidarray = [prefNetDict valueForKey:@"SSID_STR"]; - for(NSString *ssidkey in thisSsidarray) { - QString thisSsid = qt_mac_NSStringToQString(ssidkey); - if(!userProfiles.contains(thisSsid)) { - QMap map; - map.insert(thisSsid, qt_mac_NSStringToQString(nsInterfaceName)); - userProfiles.insert(thisSsid, map); + if (accessPointConfigurations.contains(cpPriv->id)) { + QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(cpPriv->id); + + bool changed = false; + + ptr->mutex.lock(); + + if (ptr->isValid != cpPriv->isValid) { + ptr->isValid = cpPriv->isValid; + changed = true; } - } - CFRelease(airportPlist); - // 802.1X user profiles - QString userProfilePath = QDir::homePath() + "/Library/Preferences/com.apple.eap.profiles.plist"; - NSDictionary* eapDict = [[NSDictionary alloc] initWithContentsOfFile:qt_mac_QStringToNSString(userProfilePath)]; - NSString *profileStr= @"Profiles"; - NSString *nameStr = @"UserDefinedName"; - NSString *networkSsidStr = @"Wireless Network"; - for (id profileKey in eapDict) { - if ([profileStr isEqualToString:profileKey]) { - NSDictionary *itemDict = [eapDict objectForKey:profileKey]; - for (id itemKey in itemDict) { + if (ptr->name != cpPriv->name) { + ptr->name = cpPriv->name; + changed = true; + } - NSInteger dictSize = [itemKey count]; - id objects[dictSize]; - id keys[dictSize]; + if (ptr->state != cpPriv->state) { + ptr->state = cpPriv->state; + changed = true; + } - [itemKey getObjects:objects andKeys:keys]; - QString networkName; - QString ssid; - for(int i = 0; i < dictSize; i++) { - if([nameStr isEqualToString:keys[i]]) { - networkName = qt_mac_NSStringToQString(objects[i]); - } - if([networkSsidStr isEqualToString:keys[i]]) { - ssid = qt_mac_NSStringToQString(objects[i]); - } - if(!userProfiles.contains(networkName) - && !ssid.isEmpty()) { - QMap map; - map.insert(ssid, qt_mac_NSStringToQString(nsInterfaceName)); - userProfiles.insert(networkName, map); - } - } - } - [itemDict release]; + ptr->mutex.unlock(); + + if (changed) { + locker.unlock(); + emit configurationChanged(ptr); + locker.relock(); } + + delete cpPriv; + } else { + QNetworkConfigurationPrivatePointer ptr(cpPriv); + + accessPointConfigurations.insert(ptr->id, ptr); + + locker.unlock(); + emit configurationAdded(ptr); + locker.relock(); } - [eapDict release]; } + + while (!previous.isEmpty()) { + QNetworkConfigurationPrivatePointer ptr = + accessPointConfigurations.take(previous.takeFirst()); + + locker.unlock(); + emit configurationRemoved(ptr); + locker.relock(); + } + + locker.unlock(); + emit updateCompleted(); + } -QT_END_NAMESPACE -#endif // QT_NO_BEARERMANAGEMENT +QT_END_NAMESPACE -- cgit v0.12 From 73a1291a3f097787f00d79d0d27bd75219bf8e3d Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 19 Apr 2010 08:58:24 +0200 Subject: Report the error as being AlreadyExists if this is why it fails On Windows it would never report this error, and on Unix it would report a different error ulimately instead as it tried to obtain the semaphore a second time which could cause a different error to what should be reported. Task-number: QTBUG-9610 Reviewed-by: Frans Englich --- src/corelib/kernel/qsystemsemaphore_unix.cpp | 2 +- src/corelib/kernel/qsystemsemaphore_win.cpp | 8 +++++-- .../qsystemsemaphore/tst_qsystemsemaphore.cpp | 25 ++++++++++++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/corelib/kernel/qsystemsemaphore_unix.cpp b/src/corelib/kernel/qsystemsemaphore_unix.cpp index 07e3618..d6c6c37 100644 --- a/src/corelib/kernel/qsystemsemaphore_unix.cpp +++ b/src/corelib/kernel/qsystemsemaphore_unix.cpp @@ -145,10 +145,10 @@ key_t QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode) // Get semaphore semaphore = semget(unix_key, 1, 0666 | IPC_CREAT | IPC_EXCL); if (-1 == semaphore) { + setErrorString(QLatin1String("QSystemSemaphore::handle")); if (errno == EEXIST) semaphore = semget(unix_key, 1, 0666 | IPC_CREAT); if (-1 == semaphore) { - setErrorString(QLatin1String("QSystemSemaphore::handle")); cleanHandle(); return -1; } diff --git a/src/corelib/kernel/qsystemsemaphore_win.cpp b/src/corelib/kernel/qsystemsemaphore_win.cpp index 96a47f5..74f253a 100644 --- a/src/corelib/kernel/qsystemsemaphore_win.cpp +++ b/src/corelib/kernel/qsystemsemaphore_win.cpp @@ -69,6 +69,10 @@ void QSystemSemaphorePrivate::setErrorString(const QString &function) error = QSystemSemaphore::PermissionDenied; errorString = QCoreApplication::translate("QSystemSemaphore", "%1: permission denied").arg(function); break; + case ERROR_ALREADY_EXISTS: + error = QSystemSemaphore::AlreadyExists; + errorString = QCoreApplication::translate("QSystemSemaphore", "%1: already exists").arg(function); + break; default: errorString = QCoreApplication::translate("QSystemSemaphore", "%1: unknown error %2").arg(function).arg(windowsError); error = QSystemSemaphore::UnknownError; @@ -88,8 +92,8 @@ HANDLE QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode) if (semaphore == 0) { QString safeName = makeKeyFileName(); semaphore = CreateSemaphore(0, initialValue, MAXLONG, (wchar_t*)safeName.utf16()); - if (semaphore == NULL) - setErrorString(QLatin1String("QSystemSemaphore::handle")); + // If the semaphore exists then the handle is still valid but there is still an error + setErrorString(QLatin1String("QSystemSemaphore::handle")); } return semaphore; diff --git a/tests/auto/qtipc/qsystemsemaphore/tst_qsystemsemaphore.cpp b/tests/auto/qtipc/qsystemsemaphore/tst_qsystemsemaphore.cpp index eb82fd4..0dc9c99 100644 --- a/tests/auto/qtipc/qsystemsemaphore/tst_qsystemsemaphore.cpp +++ b/tests/auto/qtipc/qsystemsemaphore/tst_qsystemsemaphore.cpp @@ -76,6 +76,8 @@ private slots: void undo(); void initialValue(); + void exists(); + private: QSystemSemaphore *existingLock; @@ -297,6 +299,29 @@ void tst_QSystemSemaphore::initialValue() release.waitForFinished(LACKYWAITTIME); QVERIFY(acquire.state()== QProcess::NotRunning); } + +void tst_QSystemSemaphore::exists() +{ + QSystemSemaphore sem("store", 1, QSystemSemaphore::Create); + QVERIFY(sem.error() == QSystemSemaphore::NoError); + QVERIFY(sem.acquire()); + QVERIFY(sem.error() == QSystemSemaphore::NoError); + + { + QSystemSemaphore dupSem("store", 1, QSystemSemaphore::Create); + QVERIFY(dupSem.error() == QSystemSemaphore::AlreadyExists); + } +#ifndef Q_OS_UNIX + // The rest of the test does not make sense on Unix because open will + // actually succeed anyway (see QSystemSemaphore docs) + QSystemSemaphore anotherSem("store", 1, QSystemSemaphore::Open); + QVERIFY(anotherSem.error() == QSystemSemaphore::AlreadyExists); + QVERIFY(sem.release()); + QVERIFY(anotherSem.acquire()); + QVERIFY(anotherSem.release()); +#endif +} + QTEST_MAIN(tst_QSystemSemaphore) #include "tst_qsystemsemaphore.moc" -- cgit v0.12 From 0a509ce8633c49e19f52c08b74c9b54d0227f033 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 19 Apr 2010 10:01:50 +0200 Subject: Fix compile warning. --- tools/designer/src/components/propertyeditor/propertyeditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/designer/src/components/propertyeditor/propertyeditor.cpp b/tools/designer/src/components/propertyeditor/propertyeditor.cpp index 86d7bdf..a8ca8ad 100644 --- a/tools/designer/src/components/propertyeditor/propertyeditor.cpp +++ b/tools/designer/src/components/propertyeditor/propertyeditor.cpp @@ -135,7 +135,7 @@ QSize ElidingLabel::sizeHint() const return size; } -void ElidingLabel::paintEvent(QPaintEvent *e) { +void ElidingLabel::paintEvent(QPaintEvent *) { QPainter painter(this); painter.setPen(QColor(0, 0, 0, 60)); painter.setBrush(QColor(255, 255, 255, 40)); -- cgit v0.12 From a0b75798032cb9916121ebc2277c9a950aa9a26f Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 19 Apr 2010 10:51:25 +0200 Subject: I10n: Update German translations for 4.7.0 --- translations/assistant_de.ts | 40 +-- translations/designer_de.ts | 95 ++++-- translations/linguist_de.ts | 27 +- translations/qt_de.ts | 744 +++++++++++++++++++++++++++++++------------ translations/qt_help_de.ts | 26 +- 5 files changed, 648 insertions(+), 284 deletions(-) diff --git a/translations/assistant_de.ts b/translations/assistant_de.ts index 0a0d37f..bfafc71 100644 --- a/translations/assistant_de.ts +++ b/translations/assistant_de.ts @@ -147,7 +147,7 @@ Grund: Lesezeichen verwalten... - + Add Bookmark... Lesezeichen hinzufügen ... @@ -190,7 +190,7 @@ Grund: CentralWidget - + Add new page Neue Seite hinzufügen @@ -488,19 +488,19 @@ Grund: MainWindow - + Index Index - - + + Contents Inhalt - - + + Bookmarks Lesezeichen @@ -510,14 +510,14 @@ Grund: Suchen - - + + Qt Assistant Qt Assistant - + Page Set&up... S&eite einrichten ... @@ -532,17 +532,17 @@ Grund: &Drucken ... - + New &Tab Neuer &Reiter - + &Close Tab Reiter &schließen - + &Quit &Beenden @@ -662,17 +662,17 @@ Grund: Ctrl+Alt+Left - + Could not register file '%1': %2 Die Datei '%1' konnte nicht registriert werden: %2 - + About... Über ... - + Navigation Toolbar Navigationsleiste @@ -717,12 +717,12 @@ Grund: Suchindex wird aufgebaut - + Looking for Qt Documentation... Suche nach Qt-Dokumentation ... - + &Window &Fenster @@ -742,12 +742,12 @@ Grund: Zoom - + &File &Datei - + &Edit &Bearbeiten diff --git a/translations/designer_de.ts b/translations/designer_de.ts index 475a5d5..b508b7f 100644 --- a/translations/designer_de.ts +++ b/translations/designer_de.ts @@ -180,12 +180,12 @@ BrushPropertyManager - + Style Stil - + No brush Kein Muster @@ -260,7 +260,7 @@ Kreuzende Diagonalen - + Color Farbe @@ -741,7 +741,7 @@ Designer - + Qt Designer Qt Designer @@ -1202,7 +1202,7 @@ MainWindowBase - + Main Not currently used (main tool bar) Haupt-Werkzeugleiste @@ -1579,7 +1579,7 @@ Script: %3 QDesignerActions - + Edit Widgets Widgets bearbeiten @@ -1604,17 +1604,17 @@ Script: %3 Einstellungen... - + Clear &Menu Menü &löschen - + CTRL+SHIFT+S CTRL+SHIFT+S - + CTRL+R CTRL+R @@ -1668,7 +1668,7 @@ Script: %3 Designer-UI-Dateien (*.%1);;Alle Dateien (*) - + %1 already exists. Do you want to replace it? Die Datei %1 existiert bereits. @@ -1680,7 +1680,7 @@ Möchten Sie sie überschreiben? Das Formular %1 wurde gespeichert... - + &Recent Forms &Zuletzt bearbeitete Formulare @@ -1764,7 +1764,7 @@ Möchten Sie einen anderen Namen eingeben oder ein neues Formular erzeugen?Vorschau &schließen - + Save &Image... &Vorschaubild speichern... @@ -1779,7 +1779,7 @@ Möchten Sie einen anderen Namen eingeben oder ein neues Formular erzeugen?&Zusätzliche Schriftarten... - + The file %1 could not be opened. Reason: %2 Would you like to retry or select a different file? @@ -1813,7 +1813,7 @@ Möchten Sie es noch einmal versuchen? Die Datei %1 konnte nicht geschrieben werden. - + &New... &Neu... @@ -1844,17 +1844,17 @@ Möchten Sie es noch einmal versuchen? - + &Close &Schließen - + View &Code... &Code anzeigen... - + Save Form As Formular unter einem anderen Namen speichern @@ -1886,7 +1886,7 @@ Möchten Sie es noch einmal versuchen? %1 wurde gedruckt. - + ALT+CTRL+S ALT+CTRL+S @@ -2085,7 +2085,7 @@ Möchten Sie es noch einmal versuchen? QDesignerPropertySheet - + Dynamic Properties Dynamische Eigenschaften @@ -2098,14 +2098,14 @@ Möchten Sie es noch einmal versuchen? Der Layout-Typ '%1' wird nicht unterstützt; es wurde ein Grid-Layout erzeugt. - + The container extension of the widget '%1' (%2) returned a widget not managed by Designer '%3' (%4) when queried for page #%5. Container pages should only be added by specifying them in XML returned by the domXml() method of the custom widget. Die Container-Extension des Widgets '%1' (%2) gab für Seite %5 ein Widget '%3' (%4) zurück, was nicht von Designer verwaltet wird. Container-Seiten sollten ausschließlich im XML der domXML()-Methode spezifiziert werden. - + Unexpected element <%1> Parsing clipboard contents Ungültiges Element <%1> @@ -2207,12 +2207,12 @@ Container-Seiten sollten ausschließlich im XML der domXML()-Methode spezifizier Werkzeugleisten - + Save Forms? Formulare speichern? - + &View &Ansicht @@ -2227,7 +2227,7 @@ Container-Seiten sollten ausschließlich im XML der domXML()-Methode spezifizier Widgetbox - + If you do not review your documents, all your changes will be lost. Die Änderungen gehen verloren, wenn Sie sich die Formulare nicht noch einmal ansehen. @@ -3497,7 +3497,7 @@ Dies kann zum Beispiel eine Sprachkennung wie "_de" sein. QtResourceView - + Size: %1 x %2 %3 Größe: %1 x %2 @@ -3908,6 +3908,26 @@ Möchten Sie sie überschreiben? + File + Datei + + + + Edit + Bearbeiten + + + + Tools + Werkzeuge + + + + Form + Formular + + + Toolbars Werkzeugleisten @@ -4698,9 +4718,14 @@ Möchten Sie sie überschreiben? qdesigner_internal::FilterWidget - - <Filter> - <Filter> + + Filter + Filter + + + + Clear text + Text löschen @@ -4827,7 +4852,7 @@ Möchten Sie sie überschreiben? qdesigner_internal::FormWindowBase - + Delete Löschen @@ -4997,7 +5022,7 @@ Möchten Sie sie überschreiben? Formular&einstellungen... - + Break Layout Layout auflösen @@ -5018,7 +5043,7 @@ Möchten Sie sie überschreiben? Formulareinstellungen - %1 - + Removes empty columns and rows Entfernt unbesetzte Zeilen und Spalten @@ -5975,7 +6000,7 @@ ate the goose who was loose. qdesigner_internal::PropertyEditor - + Add Dynamic Property... Dynamische Eigenschaft hinzufügen... @@ -5995,14 +6020,14 @@ ate the goose who was loose. Detailansicht - + Object: %1 Class: %2 Objekt: %1 Klasse: %2 - + Sorting Sortiert @@ -6012,7 +6037,7 @@ Klasse: %2 Farbige Hervorhebung - + Configure Property Editor Anzeige der Eigenschaften konfigurieren diff --git a/translations/linguist_de.ts b/translations/linguist_de.ts index 14095ba..5597458 100644 --- a/translations/linguist_de.ts +++ b/translations/linguist_de.ts @@ -453,7 +453,7 @@ Es wird mit einer einfachen Universalform gearbeitet. Ctrl+Q - + &Save &Speichern @@ -909,7 +909,7 @@ Es wird mit einer einfachen Universalform gearbeitet. Freigeben unter ... - + This is the application's main window. @@ -1023,12 +1023,12 @@ Soll die erstgenannte Datei übersprungen werden? - + Release Freigeben - + Qt message files for released applications (*.qm) All files (*) Qt-Nachrichtendateien (*.qm) @@ -1095,7 +1095,7 @@ Alle Dateien (*) - + @@ -1104,7 +1104,7 @@ Alle Dateien (*) Qt Linguist - + Cannot find the string '%1'. Kann Zeichenkette '%1' nicht finden. @@ -1233,7 +1233,7 @@ Alle Dateien (*) Es wurden alle Übersetzungseinheiten abgearbeitet. - + &Window &Fenster @@ -1493,7 +1493,7 @@ Alle Dateien (*) Display information about the Qt toolkit by Nokia. - + Zeigt Informationen über das Qt-Toolkit von Nokia an. @@ -1797,7 +1797,7 @@ Zeile: %2 Kompilierte Qt-Übersetzungen - + Translation files (%1);; Übersetzungsdateien (%1);; @@ -1818,11 +1818,16 @@ Zeile: %2 Qt Linguist - + GNU Gettext localization files GNU-Gettext-Übersetzungsdateien + + GNU Gettext localization template files + Vorlagen für GNU-Gettext-Übersetzungsdateien + + Qt translation sources (format 1.1) Qt-Übersetzungsdateien (Formatversion 1.1) @@ -1838,7 +1843,7 @@ Zeile: %2 Qt-Übersetzungsdateien (aktuelles Format) - + XLIFF localization files XLIFF-Übersetzungsdateien diff --git a/translations/qt_de.ts b/translations/qt_de.ts index ec7e786..86d5edb 100644 --- a/translations/qt_de.ts +++ b/translations/qt_de.ts @@ -12,7 +12,7 @@ FakeReply - + Fake error ! Fake error ! @@ -25,7 +25,7 @@ MAC_APPLICATION_MENU - + Services Dienste @@ -44,6 +44,21 @@ Show All Alle anzeigen + + + Preferences... + Einstellungen... + + + + Quit %1 + %1 beenden + + + + About %1 + Über %1 + Phonon:: @@ -81,25 +96,32 @@ Phonon::AudioOutput - + + <html>The audio playback device <b>%1</b> does not work.<br/>Falling back to <b>%2</b>.</html> <html>Das Audiogerät <b>%1</b> funktioniert nicht.<br/>Es wird stattdessen <b>%2</b> verwendet.</html> - + <html>Switching to the audio playback device <b>%1</b><br/>which just became available and has higher preference.</html> <html>Das Audiogerät <b>%1</b> wurde aktiviert,<br/>da es gerade verfügbar und höher priorisiert ist.</html> + Revert back to device '%1' Zurückschalten zum Gerät '%1' + + + <html>Switching to the audio playback device <b>%1</b><br/>which has higher preference or is specifically configured for this stream.</html> + <html>Es wird zum Audiogerät <b>%1</b> geschaltet, <br/>da es höher priorisiert ist oder spezifisch für diesen Stream konfiguriert wurde.</html> + Phonon::Gstreamer::Backend - + Warning: You do not seem to have the package gstreamer0.10-plugins-good installed. Some video features have been disabled. Achtung: Das Paket gstreamer0.10-plugins-good ist nicht installiert. @@ -116,7 +138,7 @@ Die Audio- und Video-Unterstützung steht nicht zur Verfügung. Phonon::Gstreamer::MediaObject - + Cannot start playback. Check your GStreamer installation and make sure you @@ -126,29 +148,39 @@ have libgstreamer-plugins-base installed. Bitte überprüfen Sie Ihre GStreamer-Installation und stellen Sie sicher, dass das Paket libgstreamer-plugins-base installiert ist. - + + Missing codec helper script assistant. + Der Skript-Hilfsassistent des Codecs fehlt. + + + + Plugin codec installation failed for codec: %0 + Die Installation des Codec-Plugins schlug fehl für: %0 + + + A required codec is missing. You need to install the following codec(s) to play this content: %0 Es sind nicht alle erforderlichen Codecs installiert. Um diesen Inhalt abzuspielen, muss der folgende Codec installiert werden: %0 - - - - + - - + + + + + Could not open media source. Die Medienquelle konnte nicht geöffnet werden. - + Invalid source type. Ungültiger Typ der Medienquelle. - + Could not locate media source. Die Medienquelle konnte nicht gefunden werden. @@ -350,12 +382,40 @@ Bitte überprüfen Sie Ihre GStreamer-Installation und stellen Sie sicher, dass Die Lautstärke konnte nicht eingestellt werden - + + Loading clip failed + Das Laden des Clips schlug fehl + + + Playback complete Abspielen beendet + Phonon::MMF::AbstractVideoPlayer + + + Pause failed + Fehler bei Pause-Funktion + + + + Seek failed + Suchoperation fehlgeschlagen + + + + Getting position failed + Die Position konnte nicht bestimmt werden + + + + Opening clip failed + Der Clip konnte nicht geöffnet werden + + + Phonon::MMF::AudioEqualizer @@ -370,10 +430,17 @@ Bitte überprüfen Sie Ihre GStreamer-Installation und stellen Sie sicher, dass Getting position failed Die Position konnte nicht bestimmt werden + + + Phonon::MMF::DsaVideoPlayer - - Opening clip failed - Der Clip konnte nicht geöffnet werden + + + + + + Video display error + Fehler bei der Video-Anzeige @@ -450,7 +517,7 @@ Bitte überprüfen Sie Ihre GStreamer-Installation und stellen Sie sicher, dass Phonon::MMF::MediaObject - + Error opening source: type not supported Die Quelle konnte nicht geöffnet werden: Dieser Typ wird nicht unterstützt @@ -469,38 +536,10 @@ Bitte überprüfen Sie Ihre GStreamer-Installation und stellen Sie sicher, dass - Phonon::MMF::VideoPlayer - - - Pause failed - Fehler bei Pause-Funktion - + Phonon::MMF::SurfaceVideoPlayer + - Seek failed - Suchoperation fehlgeschlagen - - - - Getting position failed - Die Position konnte nicht bestimmt werden - - - - Opening clip failed - Der Clip konnte nicht geöffnet werden - - - - Buffering clip failed - Fehler beim Puffern des Clips - - - - - - - Video display error Fehler bei der Video-Anzeige @@ -1236,7 +1275,7 @@ nach Diese Socket-Operation wird nicht unterstützt - + Socket operation timed out Das Zeitlimit für die Operation wurde überschritten @@ -1281,7 +1320,7 @@ nach QApplication - + QT_LAYOUT_DIRECTION Translate this string to the string 'LTR' in left-to-right languages or to 'RTL' in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout. LTR @@ -1409,7 +1448,7 @@ nach QComboBox - + Open Öffnen @@ -1558,7 +1597,7 @@ nach QDeclarativeAbstractAnimation - + Cannot animate non-existent property "%1" Die Eigenschaft '%1" existiert nicht und kann daher nicht animiert werden @@ -1571,19 +1610,19 @@ nach QDeclarativeAnchors - + Possible anchor loop detected on fill. Bei der Fülloperation wurde eine potentielle Endlosschleife der Anker festgestellt. - + Possible anchor loop detected on centerIn. Bei der Operation 'centerIn' wurde eine potentielle Endlosschleife der Anker festgestellt. - + - + Cannot anchor to an item that isn't a parent or sibling. Das Ziel eines Anker muss ein Elternelement oder Element der gleichen Ebene sein. @@ -1639,7 +1678,7 @@ nach QDeclarativeBehavior - + Cannot change the animation assigned to a Behavior. Die zu einem Behavior-Element gehörende Animation kann nicht geändert werden. @@ -1647,7 +1686,15 @@ nach QDeclarativeBinding - + + Binding loop detected for property "%1" + Bei der für die Eigenschaft "%1" angegebenen Bindung wurde eine Endlosschleife festgestellt + + + + QDeclarativeCompiledBindings + + Binding loop detected for property "%1" Bei der für die Eigenschaft "%1" angegebenen Bindung wurde eine Endlosschleife festgestellt @@ -1655,16 +1702,17 @@ nach QDeclarativeCompiler - - + + + - + Invalid property assignment: "%1" is a read-only property Ungültige Zuweisung bei Eigenschaft: "%1" ist schreibgeschützt - + Invalid property assignment: unknown enumeration Ungültige Zuweisung bei Eigenschaft: Ungültiger Aufzählungswert @@ -1749,12 +1797,12 @@ nach Ungültige Zuweisung bei Eigenschaft: Der Typ "%1" ist nicht unterstützt - + Element is not creatable. Das Element kann nicht erzeugt werden. - + Component elements may not contain properties other than id Komponenten dürfen außer id keine weiteren Eigenschaften enthalten. @@ -1770,12 +1818,12 @@ nach - + id is not unique ID-Wert nicht eindeutig - + Invalid component body specification Inhalt der Komponente ungültig @@ -1785,7 +1833,7 @@ nach Es kann keine leere Komponentenangabe erzeugt werden - + Invalid Script block. Specify either the source property or inline script Ungültiges Skript. Es muss die Eigenschaft oder ein eingebettetes Skript angegeben werden @@ -1795,7 +1843,7 @@ nach Ungültige Angabe für Skript - + Properties cannot be set on Script block Für ein Skript können keine Eigenschaften angegeben werden @@ -1805,12 +1853,7 @@ nach Ungültiges Skript - - Incorrectly specified signal - Ungültige Signalspezifikation - - - + Empty signal assignment Leere Signalzuweisung @@ -1843,12 +1886,12 @@ nach - + Cannot assign to non-existent property "%1" Es kann keine Zuweisung erfolgen, da keine Eigenschaft des Namens '%1" existiert - + Invalid use of namespace Ungültige Verwendung eines Namensraums @@ -1863,23 +1906,18 @@ nach Ungültige Verwendung einer Eigenschaft des Typs 'Id' - - id conflicts with type name - Der Wert der Id ist ungültig, da er bereits als Typnamen vergeben ist - - - - id conflicts with namespace prefix - Der Wert der Id ist ungültig, da er bereits als Namensraum vergeben ist + + Incorrectly specified signal assignment + - + Property has already been assigned a value Der Eigenschaft wurde bereits ein Wert zugewiesen - + Invalid grouped property access Falsche Gruppierung bei Zugriff auf Eigenschaft @@ -1895,7 +1933,7 @@ nach Ungültige Verwendung von Eigenschaften - + Property assignment expected Zuweisung an Eigenschaft erwartet @@ -1945,7 +1983,7 @@ nach "%1" kann nicht auf "%2" angewandt werden - + Duplicate default property Mehrfaches Auftreten der Vorgabe-Eigenschaft @@ -2000,7 +2038,7 @@ nach Ungültiger Typ der Eigenschaft - + Invalid empty ID Ungültiger (leerer) Id-Wert @@ -2050,7 +2088,7 @@ nach QDeclarativeComponent - + Invalid empty URL Ungültige (leere) URL @@ -2058,18 +2096,13 @@ nach QDeclarativeCompositeTypeManager - - + + Resource %1 unavailable Auf die Ressource %1 konnte nicht zugegriffen werden - - Import %1 unavailable - Import %1 nicht verfügbar - - - + Namespace %1 cannot be used as a type Der Namensraum %1 kann nicht als Typangabe verwendet werden @@ -2079,7 +2112,7 @@ nach %1 ist keine Typangabe - + Type %1 unavailable Der Typ %1 ist nicht verfügbar @@ -2142,11 +2175,48 @@ nach SQL: database version mismatch SQL: Die Version der Datenbank entspricht nicht der erwarteten Version + + + module "%1" definition "%2" not readable + Modul "%1" Definition "%2" kann nicht gelesen werden + + + + plugin cannot be loaded for module "%1": %2 + Das Plugin des Moduls "%1" konnte nicht geladen werden: %2 + + + + module "%1" plugin "%2" not found + Modul "%1" Plugin "%2" konnte nicht gefunden werden + + + + + module "%1" version %2.%3 is not installed + Modul "%1" Version %2.%3 ist nicht installiert + + + + module "%1" is not installed + Modul "%1" ist nicht installiert + + + + + "%1": no such directory + Das Verzeichnis "%1" existiert nicht + + + + import "%1" has no qmldir and no namespace + "qmldir" und Namensraum fehlt bei Import "%1" + QDeclarativeFlipable - + front is a write-once property 'front' kann nur einmal zugewiesen werden @@ -2159,7 +2229,7 @@ nach QDeclarativeInfo - + unknown location Unbekannter Ort @@ -2168,50 +2238,51 @@ nach QDeclarativeListModel - + remove: index %1 out of range remove: Der Index %1 ist außerhalb des gültigen Bereichs - + insert: value is not an object insert: Der Wert ist kein Objekt - + insert: index %1 out of range insert: Der Index %1 ist außerhalb des gültigen Bereichs - + move: out of range move: Außerhalb des gültigen Bereichs - + append: value is not an object append: Der Wert ist kein Objekt - + get: index %1 out of range get: Der Index %1 ist außerhalb des gültigen Bereichs - + set: value is not an object set: Der Wert ist kein Objekt - + set: index %1 out of range set: Der Index %1 ist außerhalb des gültigen Bereichs - - ListElement: cannot use default property - ListElement: Die Vorgabe-Eigenschaft kann nicht verwendet werden + + + ListElement: cannot contain nested elements + ListElement kann keine geschachtelten Elemente enthalten @@ -2219,20 +2290,28 @@ nach ListElement: Die "id"-Eigenschaft kann nicht verwendet werden - + ListElement: cannot use script for property value ListElement: Es kann kein Skript für den Wert der Eigenschaft verwendet werden - + ListModel: undefined property '%1' ListModel: Die Eigenschaft '%1' ist nicht definiert + QDeclarativeLoader + + + Loader does not support loading non-visual elements. + Das Laden nicht-visueller Elemente ist nicht unterstützt. + + + QDeclarativeParentAnimation - + Unable to preserve appearance under complex transform Das Erscheinungsbild kann bei einer komplexen Transformation nicht beibehalten werden @@ -2251,7 +2330,7 @@ nach QDeclarativeParentChange - + Unable to preserve appearance under complex transform Das Erscheinungsbild kann bei einer komplexen Transformation nicht beibehalten werden @@ -2270,7 +2349,7 @@ nach QDeclarativeParser - + Illegal character Ungültiges Zeichen @@ -2315,7 +2394,7 @@ nach Ungültiger Modifikator '%0' bei regulärem Ausdruck - + Syntax error Syntaxfehler @@ -2332,14 +2411,14 @@ nach Es wird das Element '%1' erwartet - - + + Property value set multiple times Mehrfache Zuweisung eines Wertes an eine Eigenschaft - + Expected type name Es wird ein Typname erwartet @@ -2349,17 +2428,27 @@ nach Ungültige Verwendung von Skript-Blöcken - + Invalid import qualifier ID Ungültige Id-Angabe bei Import + + Script import qualifiers must be unique. + Der für den Skript-Import angegebene Qualifizierer muss eindeutig sein. + + + + Script import requires a qualifier + Der Skript-Import erfordert die Angabe eines Qualifizierers. + + Library import requires a version Der Import einer Bibliothek erfordert eine Versionsangabe - + Expected parameter type Es wird eine Typangabe für den Parameter erwartet @@ -2384,7 +2473,7 @@ nach 'read-only' wird an dieser Stelle noch nicht unterstützt - + JavaScript declaration outside Script element Eine JavaScript-Deklaration ist außerhalb eines Skriptelementes nicht zulässig @@ -2397,15 +2486,39 @@ nach QDeclarativePauseAnimation - + Cannot set a duration of < 0 Es kann keine Zeitdauer <0 gesetzt werden + QDeclarativePixmapCache + + + Error decoding: %1: %2 + Fehler beim Decodieren: %1: %2 + + + + Failed to get image from provider: %1 + Bilddaten konnten nicht erhalten werden: %1 + + + + + Cannot open: %1 + Fehlschlag beim Öffnen: %1 + + + + Unknown Error loading %1 + Unbekannter Fehler beim Laden von %1 + + + QDeclarativePropertyAnimation - + Cannot set a duration of < 0 Es kann keine Zeitdauer <0 gesetzt werden @@ -2413,7 +2526,12 @@ nach QDeclarativePropertyChanges - + + PropertyChanges does not support creating state-specific objects. + Die Erzeugung von Objekten, die einem Zustand zugeordnet sind, wird von PropertyChanges nicht unterstützt. + + + Cannot assign to non-existent property "%1" Es kann keine Zuweisung erfolgen, da keine Eigenschaft des Namens '%1" existiert @@ -2426,7 +2544,7 @@ nach QDeclarativeTextInput - + Could not load cursor delegate Cursor-Delegate konnte nicht geladen werden @@ -2440,12 +2558,12 @@ nach QDeclarativeVME - + Unable to create object of type %1 Es konnte kein Objekt des Typs %1 erzeugt werden - + Cannot assign value %1 to property %2 Der Wert '%1' kann nicht der Eigenschaft %2 zugewiesen werden @@ -2465,7 +2583,7 @@ nach Der Signal-Eigenschaft %1 kann kein Objekt zugewiesen werden - + Cannot assign object to list Zuweisung eines Objekts an eine Liste nicht zulässig @@ -2488,7 +2606,7 @@ nach QDeclarativeVisualDataModel - + Delegate component must be Item type. Delegate-Komponente muss vom Typ 'Item' sein @@ -2496,7 +2614,7 @@ nach QDeclarativeXmlListModelRole - + An XmlRole query must not start with '/' Eine XmlRole-Abfrage darf nicht mit '/' beginnen @@ -2504,7 +2622,7 @@ nach QDeclarativeXmlRoleList - + An XmlListModel query must start with '/' or "//" Eine XmlListModel-Abfrage muss mit '/' oder "//" beginnen @@ -2530,12 +2648,12 @@ nach QDialog - + What's This? Direkthilfe - + Done Fertig @@ -2543,9 +2661,9 @@ nach QDialogButtonBox - + - + OK OK @@ -2757,7 +2875,7 @@ nach QFile - + Destination file exists Die Zieldatei existiert bereits @@ -2797,7 +2915,7 @@ nach QFileDialog - + All Files (*) Alle Dateien (*) @@ -2820,13 +2938,13 @@ nach Details - + File Datei - + Open Öffnen @@ -2836,7 +2954,7 @@ nach Speichern unter - + &Open @@ -2854,7 +2972,7 @@ nach Zuletzt besucht - + &Rename &Umbenennen @@ -2869,17 +2987,17 @@ nach &Versteckte Dateien anzeigen - + New Folder Neues Verzeichnis - + Find Directory Verzeichnis suchen - + Directories Verzeichnisse @@ -2889,8 +3007,8 @@ nach Alle Dateien (*.*) - - + + Directory: Verzeichnis: @@ -2989,7 +3107,7 @@ Möchten Sie die Datei trotzdem löschen? Unbekannt - + Show Anzeigen @@ -3005,7 +3123,7 @@ Möchten Sie die Datei trotzdem löschen? &Neues Verzeichnis - + &Choose &Auswählen @@ -3016,8 +3134,8 @@ Möchten Sie die Datei trotzdem löschen? Löschen - - + + File &name: Datei&name: @@ -3033,12 +3151,42 @@ Möchten Sie die Datei trotzdem löschen? Create New Folder Neuen Ordner erstellen + + + Go back + Zurück + + + + Go forward + Vor + + + + Go to the parent directory + Gehe zum übergeordneten Verzeichnis + + + + Create a New Folder + Neuen Ordner erstellen + + + + Change to list view mode + Wechsle zu Listenansicht + + + + Change to detail view mode + Wechsle zu Detailansicht + QFileSystemModel - + %1 TB %1 TB @@ -3418,14 +3566,14 @@ Möchten Sie die Datei trotzdem löschen? Verbindung mit %1 beendet - + Connection closed Verbindung beendet - + Host %1 not found Rechner %1 konnte nicht gefunden werden @@ -3450,7 +3598,7 @@ Möchten Sie die Datei trotzdem löschen? Unbekannter Fehler - + Connecting to host failed: %1 @@ -3522,7 +3670,7 @@ Möchten Sie die Datei trotzdem löschen? %1 - + Not connected Keine Verbindung @@ -3912,7 +4060,7 @@ Möchten Sie die Datei trotzdem löschen? QIODevice - + Permission denied Zugriff verweigert @@ -3932,7 +4080,7 @@ Möchten Sie die Datei trotzdem löschen? Kein freier Speicherplatz auf dem Gerät vorhanden - + Unknown error Unbekannter Fehler @@ -3940,7 +4088,7 @@ Möchten Sie die Datei trotzdem löschen? QInputContext - + XIM XIM @@ -3996,7 +4144,7 @@ Möchten Sie die Datei trotzdem löschen? Operation unmap fehlgeschlagen für '%1': %2 - + The plugin '%1' uses incompatible Qt library. (%2.%3.%4) [%5] Das Plugin '%1' verwendet eine inkompatible Qt-Bibliothek. (%2.%3.%4) [%5] @@ -4011,7 +4159,8 @@ Möchten Sie die Datei trotzdem löschen? Unbekannter Fehler - + + The shared library was not found. Die dynamische Bibliothek konnte nicht gefunden werden. @@ -4048,7 +4197,7 @@ Möchten Sie die Datei trotzdem löschen? QLineEdit - + Select All Alles auswählen @@ -4124,7 +4273,7 @@ Möchten Sie die Datei trotzdem löschen? - + %1: Invalid name %1: Ungültiger Name @@ -4371,7 +4520,7 @@ Möchten Sie die Datei trotzdem löschen? QMediaPlayer - + The QMediaPlayer object does not have a valid service Das QMediaPlayer-Objekt verfügt über keinen gültigen Dienst @@ -4462,7 +4611,7 @@ Möchten Sie die Datei trotzdem löschen? Hilfe - + Show Details... Details einblenden... @@ -4735,7 +4884,7 @@ Möchten Sie die Datei trotzdem löschen? QNetworkAccessManager - + Network access is disabled. Der Zugriff auf das Netzwerk ist nicht gestattet. @@ -4748,17 +4897,17 @@ Möchten Sie die Datei trotzdem löschen? Beim Herunterladen von %1 trat ein Fehler auf - Die Antwort des Servers ist: %2 - + Protocol "%1" is unknown Das Protokoll "%1" ist unbekannt - + Network session error. Fehler bei Netzwerkverbindung. - + Temporary network failure. Das Netzwerk ist zur Zeit ausgefallen. @@ -4766,7 +4915,7 @@ Möchten Sie die Datei trotzdem löschen? QNetworkReplyImpl - + Operation canceled Operation abgebrochen @@ -4775,7 +4924,7 @@ Möchten Sie die Datei trotzdem löschen? QNetworkSession - + Invalid configuration. Ungültige Konfiguration. @@ -4783,8 +4932,8 @@ Möchten Sie die Datei trotzdem löschen? QNetworkSessionPrivateImpl - - + + Unknown session error. Unbekannter Fehler bei Netzwerkverbindung. @@ -4813,7 +4962,7 @@ Möchten Sie die Datei trotzdem löschen? Das Roaming wurde abgebrochen oder ist hier nicht möglich. - + Roaming error Fehler beim Roaming @@ -4905,12 +5054,12 @@ Möchten Sie die Datei trotzdem löschen? QODBCDriver - + Unable to connect Es kann keine Verbindung aufgebaut werden - + Unable to disable autocommit 'autocommit' konnte nicht deaktiviert werden @@ -4930,7 +5079,7 @@ Möchten Sie die Datei trotzdem löschen? 'autocommit' konnte nicht aktiviert werden - + Unable to connect - Driver doesn't support all functionality required Es kann keine Verbindung aufgebaut werden weil der Treiber die benötigte Funktionalität nicht vollständig unterstützt @@ -4938,7 +5087,7 @@ Möchten Sie die Datei trotzdem löschen? QODBCResult - + QODBCResult::reset: Unable to set 'SQL_CURSOR_STATIC' as statement attribute. Please check your ODBC driver configuration QODBCResult::reset: 'SQL_CURSOR_STATIC' konnte nicht als Attribut des Befehls gesetzt werden. Bitte prüfen Sie die Konfiguration Ihres ODBC-Treibers @@ -4990,10 +5139,16 @@ Möchten Sie die Datei trotzdem löschen? QObject - + "%1" duplicates a previous role name and will be disabled. "%1" ist bereits als Name einer Rolle vergeben und wird daher deaktiviert. + + + + PulseAudio Sound Server + PulseAudio Sound Server + QPPDOptionsModel @@ -5915,7 +6070,7 @@ Bitte wählen Sie einen anderen Dateinamen. Zeitüberschreitung - + @@ -7535,7 +7690,157 @@ Bitte wählen Sie einen anderen Dateinamen. Umdrehen - + + Kanji + Kanji + + + + Muhenkan + Muhenkan + + + + Henkan + Henkan + + + + Romaji + Romaji + + + + Hiragana + Hiragana + + + + Katakana + Katakana + + + + Hiragana Katakana + Hiragana Katakana + + + + Zenkaku + Zenkaku + + + + Hankaku + Hankaku + + + + Zenkaku Hankaku + Zenkaku Hankaku + + + + Touroku + Touroku + + + + Massyo + Massyo + + + + Kana Lock + Kana Lock + + + + Kana Shift + Kana Shift + + + + Eisu Shift + Eisu Shift + + + + Eisu toggle + Eisu toggle + + + + Code input + Code-Eingabe + + + + Multiple Candidate + Mehrere Vorschläge + + + + Previous Candidate + Vorangegangener Vorschlag + + + + Hangul + Hangul + + + + Hangul Start + Hangul Anfang + + + + Hangul End + Hangul Ende + + + + Hangul Hanja + Hangul Hanja + + + + Hangul Jamo + Hangul Jamo + + + + Hangul Romaja + Hangul Romaja + + + + Hangul Jeonja + Hangul Jeonja + + + + Hangul Banja + Hangul Banja + + + + Hangul PreHanja + Hangul PreHanja + + + + Hangul PostHanja + Hangul PostHanja + + + + Hangul Special + Hangul Special + + + Ctrl Strg @@ -7569,7 +7874,7 @@ Bitte wählen Sie einen anderen Dateinamen. F%1 - + Home Page Startseite @@ -7703,7 +8008,7 @@ Bitte wählen Sie einen anderen Dateinamen. Abbrechen - + Exit Beenden @@ -8039,7 +8344,7 @@ Bitte wählen Sie einen anderen Dateinamen. QTcpServer - + Operation on socket is not supported Diese Socket-Operation wird nicht unterstützt @@ -8047,7 +8352,7 @@ Bitte wählen Sie einen anderen Dateinamen. QTextControl - + &Undo &Rückgängig @@ -8105,7 +8410,7 @@ Bitte wählen Sie einen anderen Dateinamen. QUdpSocket - + This platform does not support IPv6 Diese Plattform unterstützt kein IPv6 @@ -8205,7 +8510,7 @@ Bitte wählen Sie einen anderen Dateinamen. QWebFrame - + Request cancelled Anfrage wurde abgebrochen @@ -8238,7 +8543,7 @@ Bitte wählen Sie einen anderen Dateinamen. QWebPage - + Submit default label for Submit buttons in forms on web pages Senden @@ -8490,7 +8795,13 @@ Bitte wählen Sie einen anderen Dateinamen. Von rechts nach links - + + Missing Plug-in + Label text to be used when a plug-in is missing + Fehlendes Plugin + + + Loading... Media controller status message when the media is loading Lädt... @@ -8724,7 +9035,7 @@ Bitte wählen Sie einen anderen Dateinamen. %1 Sekunden - + Inspect Inspect Element context menu item Prüfen @@ -8748,13 +9059,13 @@ Bitte wählen Sie einen anderen Dateinamen. Gespeicherte Suchanfragen löschen - + Unknown Unknown filesize FTP directory listing item Unbekannt - + Web Inspector - %2 Web Inspector - %2 @@ -8765,12 +9076,12 @@ Bitte wählen Sie einen anderen Dateinamen. %1 (%2x%3 Pixel) - + Bad HTTP request Ungültige HTTP-Anforderung - + This is a searchable index. Enter search keywords: text that appears at the start of nearly-obsolete web pages in the form of a 'searchable index' Dieser Index verfügt über eine Suchfunktion. Geben Sie einen Suchbegriff ein: @@ -8850,22 +9161,22 @@ Bitte wählen Sie einen anderen Dateinamen. - + JavaScript Alert - %1 JavaScript-Hinweis - %1 - + JavaScript Confirm - %1 JavaScript-Bestätigung - %1 - + JavaScript Prompt - %1 JavaScript-Eingabeaufforderung - %1 - + JavaScript Problem - %1 JavaScript-Problem - %1 @@ -8875,7 +9186,7 @@ Bitte wählen Sie einen anderen Dateinamen. Das Skript dieser Webseite ist fehlerhaft. Möchten Sie es anhalten? - + Move the cursor to the next character Positionsmarke auf folgendes Zeichen setzen @@ -9096,7 +9407,7 @@ Bitte wählen Sie einen anderen Dateinamen. QWidget - + * * @@ -9104,7 +9415,7 @@ Bitte wählen Sie einen anderen Dateinamen. QWizard - + Cancel Abbrechen @@ -11927,4 +12238,27 @@ Bitte wählen Sie einen anderen Dateinamen. Das Attribut '%1' enthält einen ungültigen qualifizierten Namen: %2. + + Widget + + + Widget + Widget + + + + about:blank + about:blank + + + + Image from Qt to HTML + Bild von Qt zu HTML + + + + Pixmap from Qt to HTML + Pixmap von Qt zu HTML + + diff --git a/translations/qt_help_de.ts b/translations/qt_help_de.ts index 40d1158..c7a8103 100644 --- a/translations/qt_help_de.ts +++ b/translations/qt_help_de.ts @@ -43,7 +43,7 @@ - + Cannot open collection file: %1 Katalogdatei kann nicht geöffnet werden: %1 @@ -58,7 +58,7 @@ Die Katalogdatei '%1' existiert bereits. - + Unknown filter '%1'! Unbekannter Filter '%1'. @@ -78,12 +78,12 @@ Die Datenbank '%1' kann nicht zur Optimierung geöffnet werden. - + Cannot create directory: %1 Das Verzeichnis kann nicht angelegt werden: %1 - + Cannot copy collection file: %1 Die Katalogdatei kann nicht kopiert werden: %1 @@ -158,7 +158,7 @@ Die Datenbank-Datei %1 kann nicht geöffnet werden. - + Cannot register namespace %1! Der Namensraum %1 kann nicht registriert werden. @@ -266,7 +266,7 @@ QHelpProject - + Unknown token. Unbekanntes Token. @@ -282,16 +282,16 @@ - A virtual folder must not contain a '/' character! - Ein virtuelles Verzeichnis darf kein '/'-Zeichen enthalten. + Virtual folder has invalid syntax. + Ungültige Syntax bei Angabe des virtuellen Verzeichnisses. - - A namespace must not contain a '/' character! - Ein Namensraum darf kein '/'-Zeichen enthalten. + + Namespace has invalid syntax. + Ungültige Syntax der Namensraum-Angabe. - + Missing namespace in QtHelpProject. Fehlender Namensraum in QtHelpProject. @@ -306,7 +306,7 @@ Fehlendes Attribut in Schlagwort in Zeile %1. - + The input file %1 could not be opened! Die Eingabe-Datei %1 kann nicht geöffnet werden. -- cgit v0.12 From 22c44d7da7682fb2500c9b11c884e50ed4dcd042 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 19 Apr 2010 11:47:36 +0200 Subject: qdoc: Added online flag to the qdocconf file. To generate the offline docs, do nothing. To generate the online docs, add this to your qdocconf file: "online = true" --- tools/qdoc3/config.h | 1 + tools/qdoc3/htmlgenerator.cpp | 295 ++++++++++++++++++++++-------------------- tools/qdoc3/htmlgenerator.h | 1 + tools/qdoc3/test/qt.qdocconf | 1 + 4 files changed, 157 insertions(+), 141 deletions(-) diff --git a/tools/qdoc3/config.h b/tools/qdoc3/config.h index 980d1fb..c29becc 100644 --- a/tools/qdoc3/config.h +++ b/tools/qdoc3/config.h @@ -142,6 +142,7 @@ class Config #define CONFIG_MACRO "macro" #define CONFIG_NATURALLANGUAGE "naturallanguage" #define CONFIG_OBSOLETELINKS "obsoletelinks" +#define CONFIG_ONLINE "online" #define CONFIG_OUTPUTDIR "outputdir" #define CONFIG_OUTPUTENCODING "outputencoding" #define CONFIG_OUTPUTLANGUAGE "outputlanguage" diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index a5dc7b7..e074bb2 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -204,10 +204,18 @@ static void addLink(const QString &linkTarget, HtmlGenerator::HtmlGenerator() - : helpProjectWriter(0), inLink(false), inContents(false), - inSectionHeading(false), inTableHeader(false), numTableRows(0), - threeColumnEnumValueTable(true), funcLeftParen("\\S(\\()"), - myTree(0), slow(false), obsoleteLinks(false) + : helpProjectWriter(0), + inLink(false), + inContents(false), + inSectionHeading(false), + inTableHeader(false), + numTableRows(0), + threeColumnEnumValueTable(true), + offlineDocs(true), + funcLeftParen("\\S(\\()"), + myTree(0), + slow(false), + obsoleteLinks(false) { } @@ -262,7 +270,7 @@ void HtmlGenerator::initializeGenerator(const Config &config) HTMLGENERATOR_GENERATEMACREFS); project = config.getString(CONFIG_PROJECT); - + offlineDocs = !config.getBool(CONFIG_ONLINE); projectDescription = config.getString(CONFIG_DESCRIPTION); if (projectDescription.isEmpty() && !project.isEmpty()) projectDescription = project + " Reference Documentation"; @@ -1737,146 +1745,17 @@ void HtmlGenerator::generateHeader(const QString& title, out() << " \n"; out() << " \n"; out() << "\n"; - -#if 0 - out() << "\n"; - out() << QString("\n").arg(naturalLanguage); - - QString shortVersion; - if ((project != "Qtopia") && (project != "Qt Extended")) { - shortVersion = project + " " + shortVersion + ": "; - if (node && !node->doc().location().isEmpty()) - out() << "\n"; - - shortVersion = myTree->version(); - if (shortVersion.count(QChar('.')) == 2) - shortVersion.truncate(shortVersion.lastIndexOf(QChar('.'))); - if (!shortVersion.isEmpty()) { - if (project == "QSA") - shortVersion = "QSA " + shortVersion + ": "; - else - shortVersion = "Qt " + shortVersion + ": "; - } - } - - out() << "\n" - " " << shortVersion << protectEnc(title) << "\n"; - out() << QString("").arg(outputEncoding); - - if (!style.isEmpty()) - out() << " \n"; - - const QMap &metaMap = node->doc().metaTagMap(); - if (!metaMap.isEmpty()) { - QMapIterator i(metaMap); - while (i.hasNext()) { - i.next(); - out() << " \n"; - } - } - - navigationLinks.clear(); - - if (node && !node->links().empty()) { - QPair linkPair; - QPair anchorPair; - const Node *linkNode; - - if (node->links().contains(Node::PreviousLink)) { - linkPair = node->links()[Node::PreviousLink]; - linkNode = findNodeForTarget(linkPair.first, node, marker); - if (!linkNode || linkNode == node) - anchorPair = linkPair; - else - anchorPair = anchorForNode(linkNode); - - out() << " \n"; - - navigationLinks += "[Previous: "; - if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty()) - navigationLinks += protectEnc(anchorPair.second); - else - navigationLinks += protectEnc(linkPair.second); - navigationLinks += "]\n"; - } - if (node->links().contains(Node::ContentsLink)) { - linkPair = node->links()[Node::ContentsLink]; - linkNode = findNodeForTarget(linkPair.first, node, marker); - if (!linkNode || linkNode == node) - anchorPair = linkPair; - else - anchorPair = anchorForNode(linkNode); - - out() << " \n"; - - navigationLinks += "["; - if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty()) - navigationLinks += protectEnc(anchorPair.second); - else - navigationLinks += protectEnc(linkPair.second); - navigationLinks += "]\n"; - } - if (node->links().contains(Node::NextLink)) { - linkPair = node->links()[Node::NextLink]; - linkNode = findNodeForTarget(linkPair.first, node, marker); - if (!linkNode || linkNode == node) - anchorPair = linkPair; - else - anchorPair = anchorForNode(linkNode); - - out() << " \n"; - - navigationLinks += "[Next: "; - if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty()) - navigationLinks += protectEnc(anchorPair.second); - else - navigationLinks += protectEnc(linkPair.second); - navigationLinks += "]\n"; - } - if (node->links().contains(Node::IndexLink)) { - linkPair = node->links()[Node::IndexLink]; - linkNode = findNodeForTarget(linkPair.first, node, marker); - if (!linkNode || linkNode == node) - anchorPair = linkPair; - else - anchorPair = anchorForNode(linkNode); - out() << " \n"; - } - if (node->links().contains(Node::StartLink)) { - linkPair = node->links()[Node::StartLink]; - linkNode = findNodeForTarget(linkPair.first, node, marker); - if (!linkNode || linkNode == node) - anchorPair = linkPair; - else - anchorPair = anchorForNode(linkNode); - out() << " \n"; - } - } - - foreach (const QString &stylesheet, stylesheets) { - out() << " \n"; - } - foreach (const QString &customHeadElement, customHeadElements) { - out() << " " << customHeadElement << "\n"; - } - - out() << "\n" - #endif + if (offlineDocs) + out() << "\n"; + else out() << "\n"; + if (mainPage) generateMacRef(node, marker); out() << QString(postHeader).replace("\\" + COMMAND_VERSION, myTree->version()); -#if 0 +#if 0 // Removed for new docf format. MWS if (node && !node->links().empty()) out() << "

\n" << navigationLinks << "

\n"; #endif @@ -4371,8 +4250,6 @@ void HtmlGenerator::endLink() inObsoleteLink = false; } -QT_END_NAMESPACE - #ifdef QDOC_QML /*! @@ -4724,3 +4601,139 @@ void HtmlGenerator::generatePageIndex(const QString& fileName, CodeMarker* marke } #endif + +#if 0 // fossil removed for new doc format MWS 19/04/2010 + out() << "\n"; + out() << QString("\n").arg(naturalLanguage); + + QString shortVersion; + if ((project != "Qtopia") && (project != "Qt Extended")) { + shortVersion = project + " " + shortVersion + ": "; + if (node && !node->doc().location().isEmpty()) + out() << "\n"; + + shortVersion = myTree->version(); + if (shortVersion.count(QChar('.')) == 2) + shortVersion.truncate(shortVersion.lastIndexOf(QChar('.'))); + if (!shortVersion.isEmpty()) { + if (project == "QSA") + shortVersion = "QSA " + shortVersion + ": "; + else + shortVersion = "Qt " + shortVersion + ": "; + } + } + + out() << "\n" + " " << shortVersion << protectEnc(title) << "\n"; + out() << QString("").arg(outputEncoding); + + if (!style.isEmpty()) + out() << " \n"; + + const QMap &metaMap = node->doc().metaTagMap(); + if (!metaMap.isEmpty()) { + QMapIterator i(metaMap); + while (i.hasNext()) { + i.next(); + out() << " \n"; + } + } + + navigationLinks.clear(); + + if (node && !node->links().empty()) { + QPair linkPair; + QPair anchorPair; + const Node *linkNode; + + if (node->links().contains(Node::PreviousLink)) { + linkPair = node->links()[Node::PreviousLink]; + linkNode = findNodeForTarget(linkPair.first, node, marker); + if (!linkNode || linkNode == node) + anchorPair = linkPair; + else + anchorPair = anchorForNode(linkNode); + + out() << " \n"; + + navigationLinks += "[Previous: "; + if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty()) + navigationLinks += protectEnc(anchorPair.second); + else + navigationLinks += protectEnc(linkPair.second); + navigationLinks += "]\n"; + } + if (node->links().contains(Node::ContentsLink)) { + linkPair = node->links()[Node::ContentsLink]; + linkNode = findNodeForTarget(linkPair.first, node, marker); + if (!linkNode || linkNode == node) + anchorPair = linkPair; + else + anchorPair = anchorForNode(linkNode); + + out() << " \n"; + + navigationLinks += "["; + if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty()) + navigationLinks += protectEnc(anchorPair.second); + else + navigationLinks += protectEnc(linkPair.second); + navigationLinks += "]\n"; + } + if (node->links().contains(Node::NextLink)) { + linkPair = node->links()[Node::NextLink]; + linkNode = findNodeForTarget(linkPair.first, node, marker); + if (!linkNode || linkNode == node) + anchorPair = linkPair; + else + anchorPair = anchorForNode(linkNode); + + out() << " \n"; + + navigationLinks += "[Next: "; + if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty()) + navigationLinks += protectEnc(anchorPair.second); + else + navigationLinks += protectEnc(linkPair.second); + navigationLinks += "]\n"; + } + if (node->links().contains(Node::IndexLink)) { + linkPair = node->links()[Node::IndexLink]; + linkNode = findNodeForTarget(linkPair.first, node, marker); + if (!linkNode || linkNode == node) + anchorPair = linkPair; + else + anchorPair = anchorForNode(linkNode); + out() << " \n"; + } + if (node->links().contains(Node::StartLink)) { + linkPair = node->links()[Node::StartLink]; + linkNode = findNodeForTarget(linkPair.first, node, marker); + if (!linkNode || linkNode == node) + anchorPair = linkPair; + else + anchorPair = anchorForNode(linkNode); + out() << " \n"; + } + } + + foreach (const QString &stylesheet, stylesheets) { + out() << " \n"; + } + + foreach (const QString &customHeadElement, customHeadElements) { + out() << " " << customHeadElement << "\n"; + } + + out() << "\n" + #endif + + QT_END_NAMESPACE diff --git a/tools/qdoc3/htmlgenerator.h b/tools/qdoc3/htmlgenerator.h index 559c968..2a365e9 100644 --- a/tools/qdoc3/htmlgenerator.h +++ b/tools/qdoc3/htmlgenerator.h @@ -297,6 +297,7 @@ class HtmlGenerator : public PageGenerator bool inTableHeader; int numTableRows; bool threeColumnEnumValueTable; + bool offlineDocs; QString link; QStringList sectionNumber; QRegExp funcLeftParen; diff --git a/tools/qdoc3/test/qt.qdocconf b/tools/qdoc3/test/qt.qdocconf index cc3e436..ef6fe97 100644 --- a/tools/qdoc3/test/qt.qdocconf +++ b/tools/qdoc3/test/qt.qdocconf @@ -9,6 +9,7 @@ versionsym = version = %VERSION% description = Qt Reference Documentation url = http://qt.nokia.com/doc/4.7 +online = true sourceencoding = UTF-8 outputencoding = UTF-8 -- cgit v0.12