| 505 | } |
| 506 | |
| 507 | bool FileTree::showShellMenu(QPoint pos) |
| 508 | { |
| 509 | auto* mw = getMainWindow(m_tree); |
| 510 | |
| 511 | // menus by origin |
| 512 | std::map<int, env::ShellMenu> menus; |
| 513 | int totalFiles = 0; |
| 514 | bool warnOnEmpty = true; |
| 515 | |
| 516 | for (auto&& index : m_tree->selectionModel()->selectedRows()) { |
| 517 | auto* item = m_model->itemFromIndex(proxiedIndex(index)); |
| 518 | if (!item) { |
| 519 | continue; |
| 520 | } |
| 521 | |
| 522 | if (item->isDirectory()) { |
| 523 | warnOnEmpty = false; |
| 524 | |
| 525 | log::warn("directories do not have shell menus; '{}' selected", item->filename()); |
| 526 | |
| 527 | continue; |
| 528 | } |
| 529 | |
| 530 | if (item->isFromArchive()) { |
| 531 | warnOnEmpty = false; |
| 532 | |
| 533 | log::warn("files from archives do not have shell menus; '{}' selected", |
| 534 | item->filename()); |
| 535 | |
| 536 | continue; |
| 537 | } |
| 538 | |
| 539 | auto itor = menus.find(item->originID()); |
| 540 | if (itor == menus.end()) { |
| 541 | itor = menus.emplace(item->originID(), mw).first; |
| 542 | } |
| 543 | |
| 544 | if (!QFile::exists(item->realPath())) { |
| 545 | log::error("{}", tr("File '%1' does not exist, you may need to refresh.") |
| 546 | .arg(item->realPath())); |
| 547 | } |
| 548 | |
| 549 | itor->second.addFile(QFileInfo(item->realPath())); |
| 550 | ++totalFiles; |
| 551 | |
| 552 | if (item->isConflicted()) { |
| 553 | const auto file = m_core.directoryStructure()->searchFile( |
| 554 | item->dataRelativeFilePath().toStdWString(), nullptr); |
| 555 | |
| 556 | if (!file) { |
| 557 | log::error("file '{}' not found, data path={}, real path={}", item->filename(), |
| 558 | item->dataRelativeFilePath(), item->realPath()); |
| 559 | |
| 560 | continue; |
| 561 | } |
| 562 | |
| 563 | const auto alts = file->getAlternatives(); |
| 564 | if (alts.empty()) { |
nothing calls this directly
no test coverage detected