scummvm/gui/massadd.cpp
Jordi Vilalta Prat 2c9968fe80 - Added an engine plugin manager and moved engine specific functionality into it
- base/plugins.* reorganization

svn-id: r32045
2008-05-12 00:26:29 +00:00

185 lines
5.2 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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 "engines/engine.h"
#include "base/plugins.h"
#include "common/events.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("massadddialog"),
_dirsScanned(0),
_okButton(0),
_dirProgressText(0),
_gameProgressText(0) {
// The dir we start our scan at
_scanStack.push(startDir);
// 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, "massadddialog_caption", "Mass Add Dialog");
_dirProgressText = new StaticTextWidget(this, "massadddialog_dirprogress",
"... progress ...");
_gameProgressText = new StaticTextWidget(this, "massadddialog_gameprogress",
"... progress ...");
_okButton = new ButtonWidget(this, "massadddialog_ok", "OK", kOkCmd, Common::ASCII_RETURN);
_okButton->setEnabled(false);
new ButtonWidget(this, "massadddialog_cancel", "Cancel", kCancelCmd, Common::ASCII_ESCAPE);
}
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.getChildren(files, FilesystemNode::kListAll)) {
error("browser returned a node that is not a directory: '%s'",
dir.getPath().c_str());
}
// Run the detector on the dir
GameList candidates(EngineMan.detectGames(files));
// Just add all detected games / game variants. If we get more than one,
// that either means the directory contains multiple games, or the detector
// could not fully determine which game variant it was seeing. In either
// case, let the user choose which entries he wants to keep.
for (GameList::const_iterator cand = candidates.begin(); cand != candidates.end(); ++cand) {
GameDescriptor result = *cand;
result["path"] = dir.getPath();
_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!");
_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