Search code examples
c++qtwindowswifi

SSID remove duplicates issue


I want to remove wlan SSID duplicates from QTreeWidget or add some checking for the duplicates before displaying in the QTreeWidget.

Screenshot:

enter image description here

I have tried removing duplicates by QSet, but it removes also SSID which should be in the list, so it's not working in my case.

Sample code:

  QStringList apList;

  for (int i = 0; i < (int)pBssList->dwNumberOfItems; i++) {
       pBssEntry = (WLAN_AVAILABLE_NETWORK *)&pBssList->Network[i];
       apList << QString::fromUtf8(reinterpret_cast<char *>(pBssEntry->dot11Ssid.ucSSID), pBssEntry->dot11Ssid.uSSIDLength);
  }

  QSet<QString> apSet = QSet<QString>::fromList(apList);

for (int j = 0; j < apSet.count(); j++) {
    pBssEntry = (WLAN_AVAILABLE_NETWORK *)&pBssList->Network[j];
    qDebug() << QString::fromUtf8(reinterpret_cast<char *>(pBssEntry->dot11Ssid.ucSSID), pBssEntry->dot11Ssid.uSSIDLength);
}

The actual code is very big and complex, containing structures, vectors and vector iteration inserts QTreeWidgetItems to the QTreeWidget.

I have checked it and it removes last two SSID's as a duplicates.

I want the same behavior as is in Windows. Any ideas? Thanks.

Update:

 QMap<QString, int> apMap;

 for (int i = 0; i < (int)pBssList->dwNumberOfItems; i++) {
      pBssEntry = (WLAN_AVAILABLE_NETWORK *)&pBssList->Network[i];
      apMap.insert(QString::fromUtf8(reinterpret_cast<char *>(pBssEntry->dot11Ssid.ucSSID), pBssEntry->dot11Ssid.uSSIDLength), i);
    }

    qDebug() << apMap.count();
    qDebug() << apMap.uniqueKeys();
    QMap<QString, int>::iterator it;

    for (it = apMap.begin(); it != apMap.end(); it++) {
        qDebug() << it.key();
    }

Now it's working, but I need to fix other functionality as well.

Update: 2 Finally, I have fixed the bug and add all data to the QTreeWidget but sometimes profile column is different with SSID column. The thing is that profile is not added and it displays SSID's instead as is in Windows OS in the profile column otherwise it will be empty.

Screenshot:

enter image description here

So the code:

           for (int j = 0; j < apHash.uniqueKeys().count(); j++) {
                pBssEntry = (WLAN_AVAILABLE_NETWORK *)&pBssList->Network[j];
                if (wcslen(pBssEntry->strProfileName) != NULL) {
                    wirelessAPData.profile = QString::fromWCharArray(pBssEntry->strProfileName);
                    wirelessAPData.name = apHash.uniqueKeys().value(j);
                } else {
                    if (!apHash.uniqueKeys().value(j).isEmpty()) {
                        wirelessAPData.profile = apHash.uniqueKeys().value(j);
                        wirelessAPData.name = apHash.uniqueKeys().value(j);
                    } else {
                        wirelessAPData.profile = QObject::tr("Hidden network");
                        wirelessAPData.name = QObject::tr("Hidden network");
                    }
                }
           }

Also I have changed the QMap to QHash to make it faster and wirelessAPData is just a struct. Thanks.

Update: 3 I think there should be better solution, because these SSID's are not duplicates, they have different Flags, for example some of them have (has profile, no profile, connected) flags. Also I have created some constants with values:

3 - connected, 2 - has profile, 0 - no profile

And when I check networks with these constants values I get for example only with no profile or has profile or connected. But I need some check to display with has profile and only new with no profile. Any ideas? Thanks.

Update: 4: I have redesigned the application to support such APs (with profiles). The problem has been fixed.


Solution

  • Since QTreeWidget doesn't check whether a duplicate is inserted you need to use an additional container which supports exclusion of duplicates such as QMap or QHash.

    Before inserting the items in your tree widget check if the SSID isn't already present (as a key) in your map/hash table. If the check tells that there is such SSID, just don't insert it.