AddComponentDialog::SearchResult AddComponentDialog::searchComponentsAndDevices(
    const QString& input) {
  SearchResult       result;
  const QStringList& localeOrder = mProject.getSettings().getLocaleOrder();

  // add matching devices and their corresponding components
  QList<Uuid> devices =
      mWorkspace.getLibraryDb().getElementsBySearchKeyword<library::Device>(
          input);  // can throw
  foreach (const Uuid& devUuid, devices) {
    FilePath devFp =
        mWorkspace.getLibraryDb().getLatestDevice(devUuid);  // can throw
    if (!devFp.isValid()) continue;
    Uuid cmpUuid = Uuid::createRandom();
    Uuid pkgUuid = Uuid::createRandom();
    mWorkspace.getLibraryDb().getDeviceMetadata(devFp, &pkgUuid,
                                                &cmpUuid);  // can throw
    FilePath cmpFp =
        mWorkspace.getLibraryDb().getLatestComponent(cmpUuid);  // can throw
    if (!cmpFp.isValid()) continue;
    FilePath pkgFp =
        mWorkspace.getLibraryDb().getLatestPackage(pkgUuid);  // can throw
    SearchResultDevice& resDev = result[cmpFp].devices[devFp];
    resDev.pkgFp               = pkgFp;
    resDev.match               = true;
  }
void UnplacedComponentsDock::on_cbxSelectedDevice_currentIndexChanged(int index)
{
    Uuid deviceUuid(mUi->cbxSelectedDevice->itemData(index, Qt::UserRole).toString());
    FilePath devFp = mProjectEditor.getWorkspace().getLibrary().getLatestDevice(deviceUuid);
    if (devFp.isValid()) {
        const library::Device* device = new library::Device(devFp, true);
        FilePath pkgFp = mProjectEditor.getWorkspace().getLibrary().getLatestPackage(device->getPackageUuid());
        if (pkgFp.isValid()) {
            const library::Package* package = new library::Package(pkgFp, true);
            setSelectedDeviceAndPackage(device, package);
        } else {
            setSelectedDeviceAndPackage(nullptr, nullptr);
        }
    }
    else {
        setSelectedDeviceAndPackage(nullptr, nullptr);
    }
}
void UnplacedComponentsDock::on_cbxSelectedComponent_currentIndexChanged(int index)
{
    QUuid componentUuid = mUi->cbxSelectedComponent->itemData(index, Qt::UserRole).toUuid();
    FilePath cmpFp = mProjectEditor.getWorkspace().getLibrary().getLatestComponent(componentUuid);
    if (cmpFp.isValid())
    {
        const library::Component* component = new library::Component(cmpFp);
        setSelectedComponent(component);
    }
    else
    {
        setSelectedComponent(nullptr);
    }
}
 foreach (const Uuid& cmpUuid, components) {
   FilePath cmpFp =
       mWorkspace.getLibraryDb().getLatestComponent(cmpUuid);  // can throw
   if (!cmpFp.isValid()) continue;
   QSet<Uuid> devices =
       mWorkspace.getLibraryDb().getDevicesOfComponent(cmpUuid);  // can throw
   SearchResultComponent& resCmp = result[cmpFp];
   resCmp.match                  = true;
   foreach (const Uuid& devUuid, devices) {
     FilePath devFp =
         mWorkspace.getLibraryDb().getLatestDevice(devUuid);  // can throw
     if (!devFp.isValid()) continue;
     if (resCmp.devices.contains(devFp)) continue;
     Uuid pkgUuid = Uuid::createRandom();
     mWorkspace.getLibraryDb().getDeviceMetadata(devFp, &pkgUuid,
                                                 nullptr);  // can throw
     FilePath pkgFp =
         mWorkspace.getLibraryDb().getLatestPackage(pkgUuid);  // can throw
     SearchResultDevice& resDev = resCmp.devices[devFp];
     resDev.pkgFp               = pkgFp;
   }