scummvm/gui/browser.cpp
Vicent Marti 5f30b1f320 Merged several revisions from SVNMerge.
Fixed theme loading to use the new ArchiveMember class.

Original SVNMerge.py log:
=====================
Merged revisions 34686,34688-34689,34691-34698,34700-34705,34707-34713,34715-34722,34725-34727,34731-34732,34734-34738,34746 via svnmerge from 
https://tanoku@scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk

........
  r34686 | cyx | 2008-09-29 21:09:56 +0200 (Mon, 29 Sep 2008) | 1 line
  
  add constructor to SearchSet::Node for proper init of structure members with gcc 3.4.x (see tracker items #2120595, #2106292)
........
  r34688 | cyx | 2008-09-29 22:08:26 +0200 (Mon, 29 Sep 2008) | 1 line
  
  restrict _heXmapNum to HE versions, should fix #2135822
........
  r34689 | eriktorbjorn | 2008-09-29 22:40:58 +0200 (Mon, 29 Sep 2008) | 4 lines
  
  Since no one has come up with any better suggestion... this should fix #2123258
  ("COMI: Crash after video (SAN) play"). The eos() function won't return true
  until we've tried to read *past* the end of the stream.
........
  r34691 | tanoku | 2008-09-30 00:29:07 +0200 (Tue, 30 Sep 2008) | 1 line
  
  Ported ZipArchive::getAllNames() implementation from GUI branch.
........
  r34692 | fingolfin | 2008-09-30 11:07:03 +0200 (Tue, 30 Sep 2008) | 1 line
  
  Order alphabetically
........
  r34693 | fingolfin | 2008-09-30 11:08:17 +0200 (Tue, 30 Sep 2008) | 1 line
  
  SAGA: Removed patchesCount from SAGAGameDescription
........
  r34694 | fingolfin | 2008-09-30 11:09:39 +0200 (Tue, 30 Sep 2008) | 1 line
  
  SCUMM HE: Use FilesystemNode::openForReading() instead of 'new Common::File' (didn't cover all instances, though)
........
  r34695 | fingolfin | 2008-09-30 11:11:25 +0200 (Tue, 30 Sep 2008) | 1 line
  
  SAGA: Forgot to commit saga.h
........
  r34696 | fingolfin | 2008-09-30 11:12:02 +0200 (Tue, 30 Sep 2008) | 1 line
  
  Added multiple new open() methods to Common::File, which make it possible to use this class as a generic convenience wrapper around all kinds of SeekableReadStream; also renamed the name() method to the less confusing getName()
........
  r34697 | fingolfin | 2008-09-30 13:33:43 +0200 (Tue, 30 Sep 2008) | 1 line
  
  cleanup
........
  r34698 | tanoku | 2008-09-30 13:53:37 +0200 (Tue, 30 Sep 2008) | 1 line
  
  Fixed functionality of ZipArchive::getAllNames(). Now it expects a possibly non-empty string list and returns the amount of new filenames added to it.
........
  r34700 | fingolfin | 2008-09-30 14:27:38 +0200 (Tue, 30 Sep 2008) | 1 line
  
  Renamed Engine::quit to Engine::shouldQuit (previously, it was easily confused with Engine::quitGame); also cleaned up engine.h a bit
........
  r34701 | fingolfin | 2008-09-30 14:37:28 +0200 (Tue, 30 Sep 2008) | 1 line
  
  cleanup
........
  r34702 | fingolfin | 2008-09-30 14:38:44 +0200 (Tue, 30 Sep 2008) | 1 line
  
  AdvancedDetector: Do not (ab)use paths to keep track of files, rather, use FSNodes -- partial (?) fix for bug #2137680
........
  r34703 | fingolfin | 2008-09-30 14:58:27 +0200 (Tue, 30 Sep 2008) | 1 line
  
  SAGA: Some code cleanup
........
  r34704 | fingolfin | 2008-09-30 14:59:29 +0200 (Tue, 30 Sep 2008) | 1 line
  
  SKY: Fix detector to not (ab)use FSNode::getPath; if you want to open a FSNode, just pass it to File::open
........
  r34705 | thebluegr | 2008-09-30 15:19:14 +0200 (Tue, 30 Sep 2008) | 1 line
  
  Fixed crash when starting IHNM, a regression from commit #34693
........
  r34707 | fingolfin | 2008-09-30 17:42:19 +0200 (Tue, 30 Sep 2008) | 1 line
  
  Fixing ConfigManager::loadConfigFile
........
  r34708 | fingolfin | 2008-09-30 18:23:35 +0200 (Tue, 30 Sep 2008) | 1 line
  
  AGI: Another case where it is better to use FSNodes directly, instead of converting them to path strings
........
  r34709 | fingolfin | 2008-09-30 18:34:38 +0200 (Tue, 30 Sep 2008) | 1 line
  
  Modified FilePluginProvider to use FSNodes (instead of raw filenames / paths) in its API
........
  r34710 | fingolfin | 2008-09-30 18:38:46 +0200 (Tue, 30 Sep 2008) | 1 line
  
  AGI: Got rid of yet another unwarranted use of FSNode::getPath
........
  r34711 | fingolfin | 2008-09-30 18:53:04 +0200 (Tue, 30 Sep 2008) | 1 line
  
  AGI: Simplify WagFileParser by not reading data into a memory stream first (this was there to improve performance on systems with slow seeking; those systems should use another approach, see scummvm-devel)
........
  r34712 | thebluegr | 2008-09-30 18:55:10 +0200 (Tue, 30 Sep 2008) | 1 line
  
  Fix crash when starting ITE, a regression from commit #34705
........
  r34713 | fingolfin | 2008-09-30 19:09:41 +0200 (Tue, 30 Sep 2008) | 1 line
  
  Fix ThemeBrowser to use FSNodes, not getPath()
........
  r34715 | Kirben | 2008-10-02 16:41:50 +0200 (Thu, 02 Oct 2008) | 1 line
  
  Correct HE version for Putt-Putt Enters the Race (French/Windows).
........
  r34716 | fingolfin | 2008-10-02 18:58:59 +0200 (Thu, 02 Oct 2008) | 1 line
  
  Renamed FilesystemNode -> FSNode
........
  r34717 | fingolfin | 2008-10-02 19:08:15 +0200 (Thu, 02 Oct 2008) | 1 line
  
  cleanup
........
  r34718 | fingolfin | 2008-10-02 19:17:18 +0200 (Thu, 02 Oct 2008) | 1 line
  
  Ignore String::deleteLastChar when called on an empty string
........
  r34719 | fingolfin | 2008-10-02 19:20:21 +0200 (Thu, 02 Oct 2008) | 1 line
  
  Fix for bug #2142743: Assertion on clicking "Theme" in Options
........
  r34720 | fingolfin | 2008-10-02 19:48:01 +0200 (Thu, 02 Oct 2008) | 7 lines
  
  Engine class changed:
  - Moved initCommonGFX() && GUIErrorMessage() out of class Engine
  - got rid of the _autosavePeriod member (this prevented users from
    changing the autosave period during runtime)
  - Got rid of an evil 'using GUI::Dialog' statement
  - Clarified some Doxygen comments
........
  r34721 | fingolfin | 2008-10-02 19:52:29 +0200 (Thu, 02 Oct 2008) | 1 line
  
  Add the current dir to the global SearchSet, i.e. to SearchMan (this should fix the problems on Windows, and maybe other systems, see 'bug' #2137680)
........
  r34722 | fingolfin | 2008-10-02 19:55:08 +0200 (Thu, 02 Oct 2008) | 1 line
  
  Forgot to mention yet another Engine class change: mainMenuDialog -> openMainMenuDialog; and also forgot to commit this related file :/
........
  r34725 | fingolfin | 2008-10-02 20:11:40 +0200 (Thu, 02 Oct 2008) | 1 line
  
  typo
........
  r34726 | thebluegr | 2008-10-03 00:04:34 +0200 (Fri, 03 Oct 2008) | 1 line
  
  Merged loadHotSpotsMads() and loadHotSpotsM4()
........
  r34727 | lordhoto | 2008-10-03 02:16:21 +0200 (Fri, 03 Oct 2008) | 2 lines
  
  Fixed typos (thanks to Raziel^ for spotting them).
........
  r34731 | fingolfin | 2008-10-03 18:07:57 +0200 (Fri, 03 Oct 2008) | 1 line
  
  Fixed Engine::hasFeature to use proper types (i.e., MetaEngine::MetaEngineFeature instead of int)
........
  r34732 | fingolfin | 2008-10-03 18:14:12 +0200 (Fri, 03 Oct 2008) | 1 line
  
  SCUMM: Added french Monkey VGA variant, see bug #2129199
........
  r34734 | lordhoto | 2008-10-03 18:57:40 +0200 (Fri, 03 Oct 2008) | 2 lines
  
  Committed slightly modified patch #2034983 "Case-insensitivy and directory handling for engines".
........
  r34735 | lordhoto | 2008-10-03 20:18:42 +0200 (Fri, 03 Oct 2008) | 2 lines
  
  Check all 'kyra.dat' files in setup paths instead of only the first one found.
........
  r34736 | lordhoto | 2008-10-03 20:23:57 +0200 (Fri, 03 Oct 2008) | 2 lines
  
  Cleanup.
........
  r34737 | dreammaster | 2008-10-04 13:10:25 +0200 (Sat, 04 Oct 2008) | 1 line
  
  Bugfix to prevent NPC characters managing to walk beyond room exits without leaving the room, and thus getting stuck
........
  r34738 | fingolfin | 2008-10-04 15:09:01 +0200 (Sat, 04 Oct 2008) | 1 line
  
  Renamed some MetaEngine feature flags; removed explicit numbers from this feature flag list (nothing should rely on their specific values, anyway); added a note that Engine::hasFeature should become independant of MetaEngine::hasFeature
........
  r34746 | john_doe | 2008-10-04 23:40:14 +0200 (Sat, 04 Oct 2008) | 3 lines
  
  - Declared all stack functions as inline
  - Sleep some ms after 500 opcodes to reduce CPU load
  - Fixed odd bug in LGoP2 where text disappeared quickly without waiting for user input by returning 0x38 in sfShowPage
........

svn-id: r34749
2008-10-05 11:21:07 +00:00

257 lines
6.7 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 "gui/browser.h"
#include "gui/newgui.h"
#include "gui/ListWidget.h"
#include "common/config-manager.h"
#include "common/system.h"
#include "common/algorithm.h"
namespace GUI {
enum {
kChooseCmd = 'Chos',
kGoUpCmd = 'GoUp'
};
#ifdef MACOSX
/* On Mac OS X, use the native file selector dialog. We could do the same for
* other operating systems.
*/
BrowserDialog::BrowserDialog(const char *title, bool dirBrowser)
: Dialog("browser") {
_titleRef = CFStringCreateWithCString(0, title, CFStringGetSystemEncoding());
_isDirBrowser = dirBrowser;
}
BrowserDialog::~BrowserDialog() {
CFRelease(_titleRef);
}
int BrowserDialog::runModal() {
NavDialogRef dialogRef;
WindowRef windowRef = 0;
NavDialogCreationOptions options;
NavUserAction result;
NavReplyRecord reply;
OSStatus err;
bool choiceMade = false;
// If in fullscreen mode, switch to windowed mode
bool wasFullscreen = g_system->getFeatureState(OSystem::kFeatureFullscreenMode);
if (wasFullscreen)
g_system->setFeatureState(OSystem::kFeatureFullscreenMode, false);
// Temporarily show the real mouse
CGDisplayShowCursor(kCGDirectMainDisplay);
err = NavGetDefaultDialogCreationOptions(&options);
assert(err == noErr);
options.windowTitle = _titleRef;
// options.message = CFSTR("Select your game directory");
options.modality = kWindowModalityAppModal;
if (_isDirBrowser)
err = NavCreateChooseFolderDialog(&options, 0, 0, 0, &dialogRef);
else
err = NavCreateChooseFileDialog(&options, 0, 0, 0, 0, 0, &dialogRef);
assert(err == noErr);
windowRef = NavDialogGetWindow(dialogRef);
err = NavDialogRun(dialogRef);
assert(err == noErr);
CGDisplayHideCursor(kCGDirectMainDisplay);
result = NavDialogGetUserAction(dialogRef);
if (result == kNavUserActionChoose) {
err = NavDialogGetReply(dialogRef, &reply);
assert(err == noErr);
if (reply.validRecord && err == noErr) {
SInt32 theCount;
AECountItems(&reply.selection, &theCount);
assert(theCount == 1);
AEKeyword keyword;
FSRef ref;
char buf[4096];
err = AEGetNthPtr(&reply.selection, 1, typeFSRef, &keyword, NULL, &ref, sizeof(ref), NULL);
assert(err == noErr);
err = FSRefMakePath(&ref, (UInt8*)buf, sizeof(buf)-1);
assert(err == noErr);
_choice = Common::FSNode(buf);
choiceMade = true;
}
err = NavDisposeReply(&reply);
assert(err == noErr);
}
NavDialogDispose(dialogRef);
// If we were in fullscreen mode, switch back
if (wasFullscreen)
g_system->setFeatureState(OSystem::kFeatureFullscreenMode, true);
return choiceMade;
}
#else
/* We want to use this as a general directory selector at some point... possible uses
* - to select the data dir for a game
* - to select the place where save games are stored
* - others???
*/
BrowserDialog::BrowserDialog(const char *title, bool dirBrowser)
: Dialog("Browser") {
_isDirBrowser = dirBrowser;
_fileList = NULL;
_currentPath = NULL;
// Headline - TODO: should be customizable during creation time
new StaticTextWidget(this, "Browser.Headline", title);
// Current path - TODO: handle long paths ?
_currentPath = new StaticTextWidget(this, "Browser.Path", "DUMMY");
// Add file list
_fileList = new ListWidget(this, "Browser.List");
_fileList->setNumberingMode(kListNumberingOff);
_fileList->setEditable(false);
_backgroundType = GUI::Theme::kDialogBackgroundPlain;
// Buttons
new ButtonWidget(this, "Browser.Up", "Go up", kGoUpCmd, 0);
new ButtonWidget(this, "Browser.Cancel", "Cancel", kCloseCmd, 0);
new ButtonWidget(this, "Browser.Choose", "Choose", kChooseCmd, 0);
}
void BrowserDialog::open() {
if (ConfMan.hasKey("browser_lastpath"))
_node = Common::FSNode(ConfMan.get("browser_lastpath"));
if (!_node.isDirectory())
_node = Common::FSNode(".");
// Alway refresh file list
updateListing();
// Call super implementation
Dialog::open();
}
void BrowserDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
switch (cmd) {
case kChooseCmd:
if (_isDirBrowser) {
// If nothing is selected in the list widget, choose the current dir.
// Else, choose the dir that is selected.
int selection = _fileList->getSelected();
if (selection >= 0) {
_choice = _nodeContent[selection];
} else {
_choice = _node;
}
setResult(1);
close();
} else {
int selection = _fileList->getSelected();
if (selection < 0)
break;
if (_nodeContent[selection].isDirectory()) {
_node = _nodeContent[selection];
updateListing();
} else {
_choice = _nodeContent[selection];
setResult(1);
close();
}
}
break;
case kGoUpCmd:
_node = _node.getParent();
updateListing();
break;
case kListItemActivatedCmd:
case kListItemDoubleClickedCmd:
if (_nodeContent[data].isDirectory()) {
_node = _nodeContent[data];
updateListing();
} else {
_choice = _nodeContent[data];
setResult(1);
close();
}
break;
default:
Dialog::handleCommand(sender, cmd, data);
}
}
void BrowserDialog::updateListing() {
// Update the path display
_currentPath->setLabel(_node.getPath());
// We memorize the last visited path.
ConfMan.set("browser_lastpath", _node.getPath());
// Read in the data from the file system
Common::FSNode::ListMode listMode =
_isDirBrowser ? Common::FSNode::kListDirectoriesOnly
: Common::FSNode::kListAll;
if (!_node.getChildren(_nodeContent, listMode)) {
_nodeContent.clear();
} else {
Common::sort(_nodeContent.begin(), _nodeContent.end());
}
// Populate the ListWidget
Common::StringList list;
for (Common::FSList::iterator i = _nodeContent.begin(); i != _nodeContent.end(); ++i) {
if (!_isDirBrowser && i->isDirectory())
list.push_back(i->getDisplayName() + "/");
else
list.push_back(i->getDisplayName());
}
_fileList->setList(list);
_fileList->scrollTo(0);
// Finally, redraw
draw();
}
#endif // MACOSX
} // End of namespace GUI