Ticket #7504: launcher.diff

File launcher.diff, 10.5 KB (added by eriktorbjorn, 14 years ago)

Possible patch against current SVN

  • gui/launcher.h

     
    2727
    2828namespace GUI {
    2929
    30 class BrowserDialog;
     30class GameBrowserDialog;
    3131class ListWidget;
    3232class GraphicsWidget;
    3333
     
    4949        GraphicsWidget          *_logo;
    5050#endif
    5151        StringList              _domains;
    52         BrowserDialog   *_browser;
     52        GameBrowserDialog       *_browser;
    5353
    5454        virtual void handleScreenChanged();
    5555
  • gui/browser.h

     
    3636class StaticTextWidget;
    3737
    3838class BrowserDialog : public Dialog {
    39         typedef Common::String String;
    40         typedef Common::StringList StringList;
    4139public:
    4240        BrowserDialog(const char *title, bool dirBrowser);
    4341
     
    5250        const FilesystemNode    &getResult() { return _choice; }
    5351
    5452protected:
     53        typedef Common::String String;
     54        typedef Common::StringList StringList;
    5555#ifdef MACOSX
    5656        CFStringRef             _titleRef;
    5757#else
     
    6363        FilesystemNode  _choice;
    6464        bool                    _isDirBrowser;
    6565
     66        virtual bool validateSelection() { return true; }
     67
    6668#ifndef MACOSX
    6769        void updateListing();
    6870#endif
  • gui/launcher.cpp

     
    459459        }
    460460}
    461461
     462class GameBrowserDialog : public BrowserDialog {
     463public:
     464        GameBrowserDialog(const char *title) : BrowserDialog(title, true) {
     465        }
     466        ~GameBrowserDialog() {
     467        }
     468        String getDomain() {
     469                return _domain;
     470        }
    462471
     472protected:
     473        virtual bool validateSelection();
     474        String _domain;
     475};
     476
     477bool 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
    463585#pragma mark -
    464586
    465587LauncherDialog::LauncherDialog()
     
    520642        updateButtons();
    521643
    522644        // Create file browser dialog
    523         _browser = new BrowserDialog("Select directory with game data", true);
     645        _browser = new GameBrowserDialog("Select directory with game data");
    524646}
    525647
    526648void LauncherDialog::selectGame(const String &name) {
     
    598720}
    599721
    600722void LauncherDialog::addGame() {
    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();
    704728        }
    705729}
    706730
  • gui/browser.cpp

     
    171171}
    172172
    173173void BrowserDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
     174        bool selected = false;
    174175        switch (cmd) {
    175176        case kChooseCmd:
    176177                if (_isDirBrowser) {
     
    182183                        } else {
    183184                                _choice = _node;
    184185                        }
    185                         setResult(1);
    186                         close();
     186                        selected = true;
    187187                } else {
    188188                        int selection = _fileList->getSelected();
    189189                        if (selection < 0)
     
    193193                                updateListing();
    194194                        } else {
    195195                                _choice = _nodeContent[selection];
    196                                 setResult(1);
    197                                 close();
     196                                selected = true;
    198197                        }
    199198                }
     199                if (selected && validateSelection()) {
     200                        setResult(1);
     201                        close();
     202                }
    200203                break;
    201204        case kGoUpCmd:
    202205                _node = _node.getParent();