aboutsummaryrefslogtreecommitdiff
path: root/gui
diff options
context:
space:
mode:
authorMax Horn2007-02-18 18:23:52 +0000
committerMax Horn2007-02-18 18:23:52 +0000
commit94507bb44dc38bfaffc5a293f1160f35f56dd9b7 (patch)
tree36b0ce59297a7779f5f7e8a291806de8275e8688 /gui
parente0a7c6d7a78f306b7aa2a60eec9c698119090515 (diff)
downloadscummvm-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
Diffstat (limited to 'gui')
-rw-r--r--gui/launcher.cpp97
-rw-r--r--gui/launcher.h7
-rw-r--r--gui/massadd.cpp198
-rw-r--r--gui/massadd.h55
-rw-r--r--gui/module.mk1
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 \