| 472 | protected: |
| 473 | virtual bool validateSelection(); |
| 474 | String _domain; |
| 475 | }; |
| 476 | |
| 477 | bool GameBrowserDialog::validateSelection() { |
| 478 | // Allow user to add a new game to the list. |
| 479 | // 1) show a dir selection dialog which lets the user pick the directory |
| 480 | // the game data resides in. |
| 481 | // 2) try to auto detect which game is in the directory, if we cannot |
| 482 | // determine it uniquely preent a list of candidates to the user |
| 483 | // to pick from |
| 484 | // 3) Display the 'Edit' dialog for that item, letting the user specify |
| 485 | // an alternate description (to distinguish multiple versions of the |
| 486 | // game, e.g. 'Monkey German' and 'Monkey English') and set default |
| 487 | // options for that game. |
| 488 | |
| 489 | // User made his choice... |
| 490 | FilesystemNode dir(getResult()); |
| 491 | FSList files; |
| 492 | if (!dir.listDir(files, FilesystemNode::kListAll)) { |
| 493 | error("browser returned a node that is not a directory: '%s'", |
| 494 | dir.path().c_str()); |
| 495 | } |
| 496 | |
| 497 | // ...so let's determine a list of candidates, games that |
| 498 | // could be contained in the specified directory. |
| 499 | DetectedGameList candidates(PluginManager::instance().detectGames(files)); |
| 500 | |
| 501 | int idx; |
| 502 | if (candidates.empty()) { |
| 503 | // No game was found in the specified directory |
| 504 | MessageDialog alert("ScummVM could not find any game in the specified directory!"); |
| 505 | alert.runModal(); |
| 506 | return false; |
| 507 | } |
| 508 | |
| 509 | if (candidates.size() == 1) { |
| 510 | // Exact match |
| 511 | idx = 0; |
| 512 | } else { |
| 513 | // Display the candidates to the user and let her/him pick one |
| 514 | StringList list; |
| 515 | for (idx = 0; idx < (int)candidates.size(); idx++) |
| 516 | list.push_back(candidates[idx].description); |
| 517 | |
| 518 | ChooserDialog dialog("Pick the game:"); |
| 519 | dialog.setList(list); |
| 520 | idx = dialog.runModal(); |
| 521 | } |
| 522 | |
| 523 | if (idx < 0 || idx >= (int)candidates.size()) |
| 524 | return false; |
| 525 | |
| 526 | DetectedGame result = candidates[idx]; |
| 527 | |
| 528 | // The auto detector or the user made a choice. |
| 529 | // Pick a domain name which does not yet exist (after all, we |
| 530 | // are *adding* a game to the config, not replacing). |
| 531 | _domain = result.gameid; |
| 532 | if (ConfMan.hasGameDomain(_domain)) { |
| 533 | char suffix = 'a'; |
| 534 | _domain += suffix; |
| 535 | while (ConfMan.hasGameDomain(_domain)) { |
| 536 | assert(suffix < 'z'); |
| 537 | _domain.deleteLastChar(); |
| 538 | suffix++; |
| 539 | _domain += suffix; |
| 540 | } |
| 541 | } |
| 542 | |
| 543 | // Add the name domain |
| 544 | ConfMan.addGameDomain(_domain); |
| 545 | |
| 546 | // TODO: Setting the description field here has the drawback |
| 547 | // that the user does never notice when we upgrade our descriptions. |
| 548 | // It might be nice ot leave this field empty, and only set it to |
| 549 | // a value when the user edits the description string. |
| 550 | // However, at this point, that's impractical. Once we have a method |
| 551 | // to query all backends for the proper & full description of a given |
| 552 | // game target, we can change this (currently, you can only query |
| 553 | // for the generic gameid description; it's not possible to obtain |
| 554 | // a description which contains extended information like language, etc.). |
| 555 | ConfMan.set("description", result.description, _domain); |
| 556 | |
| 557 | ConfMan.set("gameid", result.gameid, _domain); |
| 558 | ConfMan.set("path", dir.path(), _domain); |
| 559 | |
| 560 | // Set language if specified |
| 561 | if (result.language != Common::UNK_LANG) |
| 562 | ConfMan.set("language", Common::getLanguageCode(result.language), _domain); |
| 563 | |
| 564 | // Set platform if specified |
| 565 | if (result.platform != Common::kPlatformUnknown) |
| 566 | ConfMan.set("platform", Common::getPlatformCode(result.platform), _domain); |
| 567 | |
| 568 | // Display edit dialog for the new entry |
| 569 | EditGameDialog editDialog(_domain, result.description); |
| 570 | |
| 571 | if (editDialog.runModal() <= 0) { |
| 572 | // User aborted, remove the the new domain again |
| 573 | ConfMan.removeGameDomain(_domain); |
| 574 | return false; |
| 575 | } |
| 576 | |
| 577 | // User pressed OK, so make changes permanent |
| 578 | |
| 579 | // Write config to disk |
| 580 | ConfMan.flushToDisk(); |
| 581 | return true; |
| 582 | } |
| 583 | |
| 584 | |
601 | | // Allow user to add a new game to the list. |
602 | | // 1) show a dir selection dialog which lets the user pick the directory |
603 | | // the game data resides in. |
604 | | // 2) try to auto detect which game is in the directory, if we cannot |
605 | | // determine it uniquely preent a list of candidates to the user |
606 | | // to pick from |
607 | | // 3) Display the 'Edit' dialog for that item, letting the user specify |
608 | | // an alternate description (to distinguish multiple versions of the |
609 | | // game, e.g. 'Monkey German' and 'Monkey English') and set default |
610 | | // options for that game. |
611 | | |
612 | | if (_browser->runModal() > 0) { |
613 | | // User made his choice... |
614 | | FilesystemNode dir(_browser->getResult()); |
615 | | FSList files; |
616 | | if (!dir.listDir(files, FilesystemNode::kListAll)) { |
617 | | error("browser returned a node that is not a directory: '%s'", |
618 | | dir.path().c_str()); |
619 | | } |
620 | | |
621 | | // ...so let's determine a list of candidates, games that |
622 | | // could be contained in the specified directory. |
623 | | DetectedGameList candidates(PluginManager::instance().detectGames(files)); |
624 | | |
625 | | int idx; |
626 | | if (candidates.empty()) { |
627 | | // No game was found in the specified directory |
628 | | MessageDialog alert("ScummVM could not find any game in the specified directory!"); |
629 | | alert.runModal(); |
630 | | idx = -1; |
631 | | } else if (candidates.size() == 1) { |
632 | | // Exact match |
633 | | idx = 0; |
634 | | } else { |
635 | | // Display the candidates to the user and let her/him pick one |
636 | | StringList list; |
637 | | for (idx = 0; idx < (int)candidates.size(); idx++) |
638 | | list.push_back(candidates[idx].description); |
639 | | |
640 | | ChooserDialog dialog("Pick the game:"); |
641 | | dialog.setList(list); |
642 | | idx = dialog.runModal(); |
643 | | } |
644 | | if (0 <= idx && idx < (int)candidates.size()) { |
645 | | DetectedGame result = candidates[idx]; |
646 | | |
647 | | // The auto detector or the user made a choice. |
648 | | // Pick a domain name which does not yet exist (after all, we |
649 | | // are *adding* a game to the config, not replacing). |
650 | | String domain(result.gameid); |
651 | | if (ConfMan.hasGameDomain(domain)) { |
652 | | char suffix = 'a'; |
653 | | domain += suffix; |
654 | | while (ConfMan.hasGameDomain(domain)) { |
655 | | assert(suffix < 'z'); |
656 | | domain.deleteLastChar(); |
657 | | suffix++; |
658 | | domain += suffix; |
659 | | } |
660 | | } |
661 | | |
662 | | // Add the name domain |
663 | | ConfMan.addGameDomain(domain); |
664 | | |
665 | | // TODO: Setting the description field here has the drawback |
666 | | // that the user does never notice when we upgrade our descriptions. |
667 | | // It might be nice ot leave this field empty, and only set it to |
668 | | // a value when the user edits the description string. |
669 | | // However, at this point, that's impractical. Once we have a method |
670 | | // to query all backends for the proper & full description of a given |
671 | | // game target, we can change this (currently, you can only query |
672 | | // for the generic gameid description; it's not possible to obtain |
673 | | // a description which contains extended information like language, etc.). |
674 | | ConfMan.set("description", result.description, domain); |
675 | | |
676 | | ConfMan.set("gameid", result.gameid, domain); |
677 | | ConfMan.set("path", dir.path(), domain); |
678 | | |
679 | | // Set language if specified |
680 | | if (result.language != Common::UNK_LANG) |
681 | | ConfMan.set("language", Common::getLanguageCode(result.language), domain); |
682 | | |
683 | | // Set platform if specified |
684 | | if (result.platform != Common::kPlatformUnknown) |
685 | | ConfMan.set("platform", Common::getPlatformCode(result.platform), domain); |
686 | | |
687 | | // Display edit dialog for the new entry |
688 | | EditGameDialog editDialog(domain, result.description); |
689 | | if (editDialog.runModal() > 0) { |
690 | | // User pressed OK, so make changes permanent |
691 | | |
692 | | // Write config to disk |
693 | | ConfMan.flushToDisk(); |
694 | | |
695 | | // Update the ListWidget, select the new item, and force a redraw |
696 | | updateListing(); |
697 | | selectGame(domain); |
698 | | draw(); |
699 | | } else { |
700 | | // User aborted, remove the the new domain again |
701 | | ConfMan.removeGameDomain(domain); |
702 | | } |
703 | | } |
| 723 | if (_browser->runModal()) { |
| 724 | // Update the ListWidget, select the new item, and force a redraw |
| 725 | updateListing(); |
| 726 | selectGame(_browser->getDomain()); |
| 727 | draw(); |