diff options
| author | Max Horn | 2007-02-18 18:23:52 +0000 | 
|---|---|---|
| committer | Max Horn | 2007-02-18 18:23:52 +0000 | 
| commit | 94507bb44dc38bfaffc5a293f1160f35f56dd9b7 (patch) | |
| tree | 36b0ce59297a7779f5f7e8a291806de8275e8688 | |
| parent | e0a7c6d7a78f306b7aa2a60eec9c698119090515 (diff) | |
| download | scummvm-rg350-94507bb44dc38bfaffc5a293f1160f35f56dd9b7.tar.gz scummvm-rg350-94507bb44dc38bfaffc5a293f1160f35f56dd9b7.tar.bz2 scummvm-rg350-94507bb44dc38bfaffc5a293f1160f35f56dd9b7.zip | |
Improved 'Mass Detector': Now displays a dialog which displays the scan progress to the user, and can be cancelled (the whole thing still needs to be polished)
svn-id: r25697
| -rw-r--r-- | gui/launcher.cpp | 97 | ||||
| -rw-r--r-- | gui/launcher.h | 7 | ||||
| -rw-r--r-- | gui/massadd.cpp | 198 | ||||
| -rw-r--r-- | gui/massadd.h | 55 | ||||
| -rw-r--r-- | gui/module.mk | 1 | 
5 files changed, 298 insertions, 60 deletions
| diff --git a/gui/launcher.cpp b/gui/launcher.cpp index 19a8b3062f..0c0c1649fb 100644 --- a/gui/launcher.cpp +++ b/gui/launcher.cpp @@ -36,6 +36,7 @@  #include "gui/chooser.h"  #include "gui/eval.h"  #include "gui/launcher.h" +#include "gui/massadd.h"  #include "gui/message.h"  #include "gui/newgui.h"  #include "gui/options.h" @@ -47,6 +48,7 @@  #include "sound/mididrv.h" +  using Common::ConfigManager;  namespace GUI { @@ -605,34 +607,6 @@ void LauncherDialog::updateListing() {  	updateButtons();  } -void LauncherDialog::addGameRecursive(FilesystemNode dir) { -	FSList files; -	if (!dir.listDir(files, FilesystemNode::kListAll)) { -		error("browser returned a node that is not a directory: '%s'", -				dir.path().c_str()); -	} - -	// Run the detector on the dir -	GameList candidates(PluginManager::instance().detectGames(files)); -	 -	if (candidates.size() >= 1) { -		// At least one match was found. For now we just take the first one... -		// a more sophisticated solution would do something more clever here, -		// e.g. ask the user which one to pick (make sure to display the  -		// path, too). -		GameDescriptor result = candidates[0]; -		addGameToConf(dir, result, true); -	} -	 -	 -	// Recurse into all subdirs -	for (FSList::const_iterator file = files.begin(); file != files.end(); ++file) { -		if (file->isDirectory()) { -			addGameRecursive(*file); -		} -	} -} -  void LauncherDialog::addGame() {  	bool massAdd = (_modifiers & OSystem::KBD_SHIFT) != 0; @@ -640,7 +614,8 @@ void LauncherDialog::addGame() {  		MessageDialog alert("Do you really want to run the mass game detector? "  							"This could potentially add a huge number of games.", "Yes", "No");  		if (alert.runModal() == GUI::kMessageOK && _browser->runModal() > 0) { -			addGameRecursive(_browser->getResult()); +			MassAddDialog massAddDlg(_browser->getResult()); +			massAddDlg.runModal();  		}  		return;  	} @@ -690,13 +665,34 @@ void LauncherDialog::addGame() {  		}  		if (0 <= idx && idx < (int)candidates.size()) {  			GameDescriptor result = candidates[idx]; -			addGameToConf(dir, result, false); + +			// TODO: Change the detectors to set "path" ! +			result["path"] = dir.path(); + +			Common::String domain = addGameToConf(result); + +			// Display edit dialog for the new entry +			EditGameDialog editDialog(domain, result.description()); +			if (editDialog.runModal() > 0) { +				// User pressed OK, so make changes permanent +		 +				// Write config to disk +				ConfMan.flushToDisk(); +		 +				// Update the ListWidget, select the new item, and force a redraw +				updateListing(); +				selectGame(domain); +				draw(); +			} else { +				// User aborted, remove the the new domain again +				ConfMan.removeGameDomain(domain); +			} +  		}  	}  } - -void LauncherDialog::addGameToConf(const FilesystemNode &dir, const GameDescriptor &result, bool suppressEditDialog) { +Common::String addGameToConf(const GameDescriptor &result) {  	// The auto detector or the user made a choice.  	// Pick a domain name which does not yet exist (after all, we  	// are *adding* a game to the config, not replacing). @@ -733,39 +729,26 @@ void LauncherDialog::addGameToConf(const FilesystemNode &dir, const GameDescript  	// for the generic gameid description; it's not possible to obtain  	// a description which contains extended information like language, etc.).  	if (!result.description().empty()) -		ConfMan.set("description", result.description(), domain); +		ConfMan.set("description", result["description"], domain); + +	// TODO: Instead of only setting a few selected keys, we could just copy *all* +	// non-empty key/value pairs from result (with the exception of "preferredtarget") +	// to the config domain. This way detectors could specify many more +	// settings w/o any further changes needed in the launcher code! -	ConfMan.set("gameid", result.gameid(), domain); -	ConfMan.set("path", dir.path(), domain); +	ConfMan.set("gameid", result["gameid"], domain); +	 +	ConfMan.set("path", result["path"], domain);  	// Set language if specified  	if (result.language() != Common::UNK_LANG) -		ConfMan.set("language", Common::getLanguageCode(result.language()), domain); +		ConfMan.set("language", result["language"], domain);  	// Set platform if specified  	if (result.platform() != Common::kPlatformUnknown) -		ConfMan.set("platform", Common::getPlatformCode(result.platform()), domain); +		ConfMan.set("platform", result["platform"], domain); -	// Display edit dialog for the new entry -	bool saveit = true; -	if (!suppressEditDialog) { -		EditGameDialog editDialog(domain, result.description()); -		saveit = (editDialog.runModal() > 0); -	} -	if (saveit) { -		// User pressed OK, so make changes permanent - -		// Write config to disk -		ConfMan.flushToDisk(); - -		// Update the ListWidget, select the new item, and force a redraw -		updateListing(); -		selectGame(domain); -		draw(); -	} else { -		// User aborted, remove the the new domain again -		ConfMan.removeGameDomain(domain); -	} +	return domain;  }  void LauncherDialog::removeGame(int item) { diff --git a/gui/launcher.h b/gui/launcher.h index 1730fea622..41550db992 100644 --- a/gui/launcher.h +++ b/gui/launcher.h @@ -31,6 +31,10 @@ class BrowserDialog;  class ListWidget;  class GraphicsWidget; + +Common::String addGameToConf(const GameDescriptor &result); + +  class LauncherDialog : public Dialog {  	typedef Common::String String;  	typedef Common::StringList StringList; @@ -68,9 +72,6 @@ protected:  	void editGame(int item);  	void selectGame(const String &name); -	 -	void addGameToConf(const FilesystemNode &dir, const GameDescriptor &result, bool suppressEditDialog); -	void addGameRecursive(FilesystemNode dir);  };  } // End of namespace GUI diff --git a/gui/massadd.cpp b/gui/massadd.cpp new file mode 100644 index 0000000000..10b72b2639 --- /dev/null +++ b/gui/massadd.cpp @@ -0,0 +1,198 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2002-2006 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + */ + +#include "common/stdafx.h" + +#include "engines/engine.h" +#include "base/game.h" +#include "base/plugins.h" + +#include "gui/launcher.h"	// For addGameToConf() +#include "gui/massadd.h" +#include "gui/newgui.h" +#include "gui/widget.h" + + +namespace GUI { + +/* +TODO: +- Themify this dialog +- Add a ListWidget showing all the games we are going to add, and update it live +- Add a 'busy' mouse cursor (animated?) which indicates to the user that +  something is in progress, and show this cursor while we scan +*/ + +enum { +	// Upper bound (im milliseconds) we want to spend in handleTickle. +	// Setting this low makes the GUI more responsive but also slows +	// down the scanning. +	kMaxScanTime = 50 +}; + +enum { +	kOkCmd = 'OK  ', +	kCancelCmd = 'CNCL' +}; + + + +MassAddDialog::MassAddDialog(const FilesystemNode &startDir) +	: Dialog(10, 20, 300, 174), +	_dirsScanned(0), +	_okButton(0), +	_dirProgressText(0), +	_gameProgressText(0) { + +	// The dir we start our scan at +	_scanStack.push(startDir); + + +	int buttonWidth, buttonHeight; + +	if (g_gui.getWidgetSize() == kBigWidgetSize) { +		buttonWidth = kBigButtonWidth; +		buttonHeight = kBigButtonHeight; +	} else { +		buttonWidth = kButtonWidth; +		buttonHeight = kButtonHeight; +	} + +	// Create dialog items +	// We need: +	// - "OK" button, only enabled after the scan has finished +	// - "Cancel" / "Abort" button, always active +	// - static text as headline for the dialog +	// - static text displaying the progress text +	// - (future) a listbox showing all the games we added/are going to add + +	new StaticTextWidget(this, 10, 10 + 1 * kLineHeight, _w - 2*10, kLineHeight, +								"Mass Add Dialog", kTextAlignCenter); + +	_dirProgressText = new StaticTextWidget(this, 10, 10 + 3 * kLineHeight, _w - 2*10, kLineHeight, +								"... progress ...", kTextAlignCenter); + +	_gameProgressText = new StaticTextWidget(this, 10, 10 + 4 * kLineHeight, _w - 2*10, kLineHeight, +								"... progress ...", kTextAlignCenter); + +	int okButtonPos = (_w - (buttonWidth * 2)) / 2; +	int cancelButtonPos = ((_w - (buttonWidth * 2)) / 2) + buttonWidth + 10; + +	_okButton = addButton(this, okButtonPos, _h - buttonHeight - 8, "OK", kOkCmd, '\n'); +	_okButton->setEnabled(false); + +	addButton(this, cancelButtonPos, _h - buttonHeight - 8, "Cancel", kCancelCmd, '\27'); + +} + + +void MassAddDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { +	// FIXME: It's a really bad thing that we use two arbitrary constants +	if (cmd == kOkCmd) { +		// Add all the detected games to the config +		for (GameList::const_iterator iter = _games.begin(); iter != _games.end(); ++iter) { +			printf("  Added gameid '%s', desc '%s'\n", +				(*iter)["gameid"].c_str(), +				(*iter)["description"].c_str()); +			addGameToConf(*iter); +		} + +		// Write everything to disk +		ConfMan.flushToDisk(); + +		close(); +	} else if (cmd == kCancelCmd) { +		// User cancelled, so we don't do anything and just leave. +		close(); +	} else { +		Dialog::handleCommand(sender, cmd, data); +	} +} + +void MassAddDialog::handleTickle() { +	if (_scanStack.empty()) +		return;	// We have finished scanning + +	uint32 t = g_system->getMillis(); + +	// Perform a breadth-first scan of the filesystem. +	while (!_scanStack.empty() && (g_system->getMillis() - t) < kMaxScanTime) { +		FilesystemNode dir = _scanStack.pop(); +	 +		FSList files; +		if (!dir.listDir(files, FilesystemNode::kListAll)) { +			error("browser returned a node that is not a directory: '%s'", +					dir.path().c_str()); +		} +	 +		// Run the detector on the dir +		GameList candidates(PluginManager::instance().detectGames(files)); +		 +		if (candidates.size() >= 1) { +			// At least one match was found. For now we just take the first one... +			// a more sophisticated solution would do something more clever here, +			// e.g. ask the user which one to pick (make sure to display the  +			// path, too). +			GameDescriptor result = candidates[0]; +			result["path"] = dir.path(); +			 +			_games.push_back(result); +		} +		 +		 +		// Recurse into all subdirs +		for (FSList::const_iterator file = files.begin(); file != files.end(); ++file) { +			if (file->isDirectory()) { +				_scanStack.push(*file); +			} +		} + +		_dirsScanned++; +	} +	 +	 +	// Update the dialog +	char buf[256]; + +	if (_scanStack.empty()) { +		// Enable the OK button +		_okButton->setEnabled(true); + +		snprintf(buf, sizeof(buf), "Scan complete!", _dirsScanned); +		_dirProgressText->setLabel(buf); +	 +		snprintf(buf, sizeof(buf), "Discovered %d games.", _games.size()); +		_gameProgressText->setLabel(buf); + +	} else { +		snprintf(buf, sizeof(buf), "Scanned %d directories ...", _dirsScanned); +		_dirProgressText->setLabel(buf); +	 +		snprintf(buf, sizeof(buf), "Discovered %d games ...", _games.size()); +		_gameProgressText->setLabel(buf); +	} + +	drawDialog(); +} + + +} // end of namespace GUI + diff --git a/gui/massadd.h b/gui/massadd.h new file mode 100644 index 0000000000..7fd2d2f10d --- /dev/null +++ b/gui/massadd.h @@ -0,0 +1,55 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2002-2006 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + */ + +#ifndef MASSADD_DIALOG_H +#define MASSADD_DIALOG_H + +#include "gui/dialog.h" +#include "common/fs.h" +#include "common/stack.h" + +namespace GUI { + +class StaticTextWidget; + +class MassAddDialog : public Dialog { +public: +	MassAddDialog(const FilesystemNode &startDir); + +	//void open(); +	void handleCommand(CommandSender *sender, uint32 cmd, uint32 data); +	void handleTickle(); + +private: +	Common::Stack<FilesystemNode>  _scanStack; +	GameList _games; +	 +	int _dirsScanned; + +	Widget *_okButton; +	StaticTextWidget *_dirProgressText; +	StaticTextWidget *_gameProgressText; +}; + + +} // End of namespace GUI + +#endif diff --git a/gui/module.mk b/gui/module.mk index d447820ad6..b352a1ec86 100644 --- a/gui/module.mk +++ b/gui/module.mk @@ -12,6 +12,7 @@ MODULE_OBJS := \  	eval.o \  	launcher.o \  	ListWidget.o \ +	massadd.o \  	message.o \  	newgui.o \  	options.o \ | 
