| 499 | } |
| 500 | |
| 501 | std::map<std::string, std::string> findCollisions(const QString& currentNameEntry) { |
| 502 | std::map<std::string, std::string> collisions{}; |
| 503 | |
| 504 | // default locations of desktop files on systems |
| 505 | const auto directories = { |
| 506 | QString("/usr/share/applications/"), |
| 507 | QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/applications/" |
| 508 | }; |
| 509 | |
| 510 | for (const auto& directory : directories) { |
| 511 | QDirIterator iterator(directory, QDirIterator::FollowSymlinks); |
| 512 | |
| 513 | while (iterator.hasNext()) { |
| 514 | const auto filename = iterator.next(); |
| 515 | |
| 516 | if (!QFileInfo(filename).isFile() || !filename.endsWith(".desktop")) |
| 517 | continue; |
| 518 | |
| 519 | std::shared_ptr<GKeyFile> desktopFile(g_key_file_new(), gKeyFileDeleter); |
| 520 | std::shared_ptr<GError*> error(nullptr, gErrorDeleter); |
| 521 | |
| 522 | // if the key file parser can't load the file, it's most likely not a valid desktop file, so we just skip this file |
| 523 | if (!g_key_file_load_from_file(desktopFile.get(), filename.toStdString().c_str(), G_KEY_FILE_KEEP_TRANSLATIONS, error.get())) |
| 524 | continue; |
| 525 | |
| 526 | auto* nameEntry = g_key_file_get_string(desktopFile.get(), G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, error.get()); |
| 527 | |
| 528 | // invalid desktop file, needs to be skipped |
| 529 | if (nameEntry == nullptr) |
| 530 | continue; |
| 531 | |
| 532 | if (QString(nameEntry).trimmed().startsWith(currentNameEntry.trimmed())) { |
| 533 | collisions[filename.toStdString()] = nameEntry; |
| 534 | } |
| 535 | } |
| 536 | } |
| 537 | |
| 538 | return collisions; |
| 539 | } |
| 540 | |
| 541 | bool updateDesktopDatabaseAndIconCaches() { |
| 542 | const auto dataLocation = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); |
no outgoing calls
no test coverage detected