mirror of
https://github.com/libretro/scummvm.git
synced 2024-11-30 21:00:39 +00:00
Changed the FilesystemNode implementation to make it easier to use (client code doesn't have to worry about the memory managment anymore, it's all 'automatic' now). May have introduced a mem leak or two, please check :-)
svn-id: r15848
This commit is contained in:
parent
c93f57b112
commit
5d9b35510d
1
backends/fs/.cvsignore
Normal file
1
backends/fs/.cvsignore
Normal file
@ -0,0 +1 @@
|
||||
.deps
|
78
backends/fs/fs.cpp
Normal file
78
backends/fs/fs.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
/* ScummVM - Scumm Interpreter
|
||||
* Copyright (C) 2002-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* $Header$
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "fs.h"
|
||||
|
||||
FilesystemNode AbstractFilesystemNode::wrap(AbstractFilesystemNode *node) {
|
||||
FilesystemNode wrapper;
|
||||
wrapper._realNode = node;
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
|
||||
FilesystemNode::FilesystemNode() {
|
||||
_realNode = getRoot();
|
||||
_refCount = new int(1);
|
||||
}
|
||||
|
||||
FilesystemNode::FilesystemNode(const FilesystemNode &node)
|
||||
: AbstractFilesystemNode() {
|
||||
_realNode = node._realNode;
|
||||
_refCount = node._refCount;
|
||||
++(*_refCount);
|
||||
}
|
||||
|
||||
#ifdef MACOSX
|
||||
FilesystemNode::FilesystemNode(const String &p) {
|
||||
_realNode = getNodeForPath(p);
|
||||
_refCount = new int(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
FilesystemNode::~FilesystemNode() {
|
||||
decRefCount();
|
||||
}
|
||||
|
||||
void FilesystemNode::decRefCount() {
|
||||
--(*_refCount);
|
||||
if (*_refCount <= 0) {
|
||||
delete _refCount;
|
||||
delete _realNode;
|
||||
}
|
||||
}
|
||||
|
||||
FilesystemNode &FilesystemNode::operator =(const FilesystemNode &node) {
|
||||
++(*node._refCount);
|
||||
|
||||
decRefCount();
|
||||
|
||||
_realNode = node._realNode;
|
||||
_refCount = node._refCount;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
FilesystemNode FilesystemNode::getParent() const {
|
||||
FilesystemNode wrapper;
|
||||
wrapper._realNode = _realNode->parent();
|
||||
return wrapper;
|
||||
}
|
148
backends/fs/fs.h
148
backends/fs/fs.h
@ -58,15 +58,40 @@
|
||||
#include "common/array.h"
|
||||
#include "common/str.h"
|
||||
|
||||
class FSList;
|
||||
class FilesystemNode;
|
||||
|
||||
|
||||
/**
|
||||
* List of multiple file system nodes. E.g. the contents of a given directory.
|
||||
*/
|
||||
class FSList : public Common::Array<FilesystemNode> {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* File system node.
|
||||
*/
|
||||
class FilesystemNode {
|
||||
class AbstractFilesystemNode {
|
||||
protected:
|
||||
friend class FilesystemNode;
|
||||
typedef Common::String String;
|
||||
|
||||
/**
|
||||
* The parent node of this directory.
|
||||
* The parent of the root is the root itself.
|
||||
*/
|
||||
virtual AbstractFilesystemNode *parent() const = 0;
|
||||
|
||||
/**
|
||||
* This method is a rather ugly hack which is used internally by the
|
||||
* actual node implementions to wrap up raw nodes inside FilesystemNode
|
||||
* objects. We probably want to get rid of this eventually and replace it
|
||||
* with a cleaner / more elegant solution, but for now it works.
|
||||
* @note This takes over ownership of node. Do not delete it yourself,
|
||||
* else you'll get ugly crashes. You've been warned!
|
||||
*/
|
||||
static FilesystemNode wrap(AbstractFilesystemNode *node);
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
@ -78,25 +103,7 @@ public:
|
||||
kListAll = 3
|
||||
} ListMode;
|
||||
|
||||
/**
|
||||
* Returns a special node representing the FS root. The starting point for
|
||||
* any file system browsing.
|
||||
* On Unix, this will be simply the node for / (the root directory).
|
||||
* On Windows, it will be a special node which "contains" all drives (C:, D:, E:).
|
||||
*/
|
||||
static FilesystemNode *getRoot();
|
||||
|
||||
#ifdef MACOSX
|
||||
/*
|
||||
* Construct a node based on a path; the path is in the same format as it
|
||||
* would be for calls to fopen().
|
||||
*
|
||||
* I.e. getNodeForPath(oldNode.path()) should create a new node identical to oldNode.
|
||||
*/
|
||||
static FilesystemNode *getNodeForPath(const String &path);
|
||||
#endif
|
||||
|
||||
virtual ~FilesystemNode() {}
|
||||
virtual ~AbstractFilesystemNode() {}
|
||||
|
||||
/**
|
||||
* Return display name, used by e.g. the GUI to present the file in the file browser.
|
||||
@ -123,78 +130,69 @@ public:
|
||||
* List the content of this directory node.
|
||||
* If this node is not a directory, throw an exception or call error().
|
||||
*/
|
||||
virtual FSList *listDir(ListMode mode = kListDirectoriesOnly) const = 0;
|
||||
virtual FSList listDir(ListMode mode = kListDirectoriesOnly) const = 0;
|
||||
|
||||
/**
|
||||
* The parent node of this directory.
|
||||
* The parent of the root is the root itself
|
||||
*/
|
||||
virtual FilesystemNode *parent() const = 0;
|
||||
|
||||
/**
|
||||
* Return a clone of this node allocated with new().
|
||||
*/
|
||||
virtual FilesystemNode *clone() const = 0;
|
||||
|
||||
/**
|
||||
* Compare the name of this node to the name of another.
|
||||
*/
|
||||
virtual bool operator< (const FilesystemNode& node) const
|
||||
virtual bool operator< (const AbstractFilesystemNode& node) const
|
||||
{
|
||||
return scumm_stricmp(displayName().c_str(), node.displayName().c_str()) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
class FilesystemNode : public AbstractFilesystemNode {
|
||||
friend class AbstractFilesystemNode;
|
||||
|
||||
typedef Common::String String;
|
||||
private:
|
||||
AbstractFilesystemNode *_realNode;
|
||||
int *_refCount;
|
||||
|
||||
/**
|
||||
* Returns a special node representing the FS root. The starting point for
|
||||
* any file system browsing.
|
||||
* On Unix, this will be simply the node for / (the root directory).
|
||||
* On Windows, it will be a special node which "contains" all drives (C:, D:, E:).
|
||||
*/
|
||||
static AbstractFilesystemNode *getRoot();
|
||||
|
||||
#ifdef MACOSX
|
||||
/*
|
||||
* Construct a node based on a path; the path is in the same format as it
|
||||
* would be for calls to fopen().
|
||||
*
|
||||
* I.e. getNodeForPath(oldNode.path()) should create a new node identical to oldNode.
|
||||
*/
|
||||
static AbstractFilesystemNode *getNodeForPath(const String &path);
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Sorted list of multiple file system nodes. E.g. the contents of a given directory.
|
||||
*/
|
||||
class FSList : private Common::Array<FilesystemNode *> {
|
||||
public:
|
||||
class const_iterator {
|
||||
friend class FSList;
|
||||
FilesystemNode **_data;
|
||||
const_iterator(FilesystemNode **data) : _data(data) { }
|
||||
public:
|
||||
const FilesystemNode &operator *() const { return **_data; }
|
||||
const FilesystemNode *operator->() const { return *_data; }
|
||||
bool operator !=(const const_iterator &iter) const { return _data != iter._data; }
|
||||
void operator ++() { ++_data; }
|
||||
};
|
||||
FilesystemNode();
|
||||
FilesystemNode(const FilesystemNode &node);
|
||||
#ifdef MACOSX
|
||||
FilesystemNode(const String &path);
|
||||
#endif
|
||||
~FilesystemNode();
|
||||
|
||||
~FSList() {
|
||||
for (int i = 0; i < _size; i++)
|
||||
delete _data[i];
|
||||
}
|
||||
FilesystemNode &operator =(const FilesystemNode &node);
|
||||
|
||||
void push_back(const FilesystemNode &element) {
|
||||
ensureCapacity(_size + 1);
|
||||
// Determine where to insert the item.
|
||||
// TODO this is inefficient, should use binary search instead
|
||||
int i = 0;
|
||||
while (i < _size && *_data[i] < element)
|
||||
i++;
|
||||
if (i < _size)
|
||||
memmove(&_data[i + 1], &_data[i], (_size - i) * sizeof(FilesystemNode *));
|
||||
_data[i] = element.clone();
|
||||
_size++;
|
||||
}
|
||||
FilesystemNode getParent() const;
|
||||
|
||||
const FilesystemNode& operator [](int idx) const {
|
||||
assert(idx >= 0 && idx < _size);
|
||||
return *_data[idx];
|
||||
}
|
||||
|
||||
int size() const { return _size; }
|
||||
virtual String displayName() const { return _realNode->displayName(); }
|
||||
virtual bool isValid() const { return _realNode->isValid(); }
|
||||
virtual bool isDirectory() const { return _realNode->isDirectory(); }
|
||||
virtual String path() const { return _realNode->path(); }
|
||||
|
||||
const_iterator begin() const {
|
||||
return const_iterator(_data);
|
||||
}
|
||||
virtual FSList listDir(ListMode mode = kListDirectoriesOnly) const { return _realNode->listDir(mode); }
|
||||
|
||||
const_iterator end() const {
|
||||
return const_iterator(_data + _size);
|
||||
}
|
||||
protected:
|
||||
void decRefCount();
|
||||
|
||||
virtual AbstractFilesystemNode *parent() const { return 0; }
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -31,7 +31,7 @@
|
||||
* Implementation of the ScummVM file system API based on the MorphOS A-Box API.
|
||||
*/
|
||||
|
||||
class ABoxFilesystemNode : public FilesystemNode {
|
||||
class ABoxFilesystemNode : public AbstractFilesystemNode {
|
||||
protected:
|
||||
BPTR _lock;
|
||||
String _displayName;
|
||||
@ -50,14 +50,14 @@ class ABoxFilesystemNode : public FilesystemNode {
|
||||
virtual bool isDirectory() const { return _isDirectory; }
|
||||
virtual String path() const { return _path; }
|
||||
|
||||
virtual FSList *listDir(ListMode mode = kListDirectoriesOnly) const;
|
||||
static FSList *listRoot();
|
||||
virtual FilesystemNode *parent() const;
|
||||
virtual FilesystemNode *clone() const { return new ABoxFilesystemNode(this); }
|
||||
virtual FSList listDir(ListMode mode = kListDirectoriesOnly) const;
|
||||
static FSList listRoot();
|
||||
virtual AbstractFilesystemNode *parent() const;
|
||||
virtual AbstractFilesystemNode *clone() const { return new ABoxFilesystemNode(this); }
|
||||
};
|
||||
|
||||
|
||||
FilesystemNode *FilesystemNode::getRoot()
|
||||
AbstractFilesystemNode *FilesystemNode::getRoot()
|
||||
{
|
||||
return new ABoxFilesystemNode();
|
||||
}
|
||||
@ -137,9 +137,9 @@ ABoxFilesystemNode::~ABoxFilesystemNode()
|
||||
}
|
||||
}
|
||||
|
||||
FSList *ABoxFilesystemNode::listDir(ListMode mode) const
|
||||
FSList ABoxFilesystemNode::listDir(ListMode mode) const
|
||||
{
|
||||
FSList *myList = new FSList();
|
||||
FSList myList;
|
||||
|
||||
if (!_isValid)
|
||||
error("listDir() called on invalid node");
|
||||
@ -182,8 +182,9 @@ FSList *ABoxFilesystemNode::listDir(ListMode mode) const
|
||||
if (entry)
|
||||
{
|
||||
if (entry->isValid())
|
||||
myList->push_back(*entry);
|
||||
delete entry;
|
||||
myList.push_back(wrap(entry));
|
||||
else
|
||||
delete entry;
|
||||
}
|
||||
UnLock(lock);
|
||||
}
|
||||
@ -199,9 +200,9 @@ FSList *ABoxFilesystemNode::listDir(ListMode mode) const
|
||||
return myList;
|
||||
}
|
||||
|
||||
FilesystemNode *ABoxFilesystemNode::parent() const
|
||||
AbstractFilesystemNode *ABoxFilesystemNode::parent() const
|
||||
{
|
||||
FilesystemNode *node = NULL;
|
||||
AbstractFilesystemNode *node = NULL;
|
||||
|
||||
if (!_isDirectory)
|
||||
error("parent() called on file node");
|
||||
@ -224,9 +225,9 @@ FilesystemNode *ABoxFilesystemNode::parent() const
|
||||
return node;
|
||||
}
|
||||
|
||||
FSList *ABoxFilesystemNode::listRoot()
|
||||
FSList ABoxFilesystemNode::listRoot()
|
||||
{
|
||||
FSList *myList = new FSList();
|
||||
FSList myList;
|
||||
DosList *dosList;
|
||||
CONST ULONG lockDosListFlags = LDF_READ | LDF_VOLUMES;
|
||||
char name[256];
|
||||
@ -261,8 +262,9 @@ FSList *ABoxFilesystemNode::listRoot()
|
||||
if (entry)
|
||||
{
|
||||
if (entry->isValid())
|
||||
myList->push_back(*entry);
|
||||
delete entry;
|
||||
myList.push_back(wrap(entry));
|
||||
else
|
||||
delete entry;
|
||||
}
|
||||
UnLock(volume_lock);
|
||||
}
|
||||
|
@ -29,7 +29,7 @@
|
||||
* Implementation of the ScummVM file system API based on PalmOS VFS API.
|
||||
*/
|
||||
|
||||
class PalmOSFilesystemNode : public FilesystemNode {
|
||||
class PalmOSFilesystemNode : public AbstractFilesystemNode {
|
||||
protected:
|
||||
String _displayName;
|
||||
bool _isDirectory;
|
||||
@ -47,15 +47,14 @@ public:
|
||||
virtual bool isDirectory() const { return _isDirectory; }
|
||||
virtual String path() const { return _path; }
|
||||
|
||||
virtual FSList *listDir(ListMode) const;
|
||||
virtual FilesystemNode *parent() const;
|
||||
virtual FilesystemNode *clone() const { return new PalmOSFilesystemNode(this); }
|
||||
virtual FSList listDir(ListMode) const;
|
||||
virtual AbstractFilesystemNode *parent() const;
|
||||
|
||||
private:
|
||||
static void addFile (FSList* list, ListMode mode, const Char *base, FileInfoType* find_data);
|
||||
static void addFile (FSList &list, ListMode mode, const Char *base, FileInfoType* find_data);
|
||||
};
|
||||
|
||||
void PalmOSFilesystemNode::addFile(FSList* list, ListMode mode, const char *base, FileInfoType* find_data) {
|
||||
void PalmOSFilesystemNode::addFile(FSList &list, ListMode mode, const char *base, FileInfoType* find_data) {
|
||||
PalmOSFilesystemNode entry;
|
||||
bool isDirectory;
|
||||
|
||||
@ -74,10 +73,10 @@ void PalmOSFilesystemNode::addFile(FSList* list, ListMode mode, const char *base
|
||||
|
||||
entry._isValid = true;
|
||||
entry._isPseudoRoot = false;
|
||||
list->push_back(entry);
|
||||
list.push_back(wrap(new PalmOSFilesystemNode(&entry)));
|
||||
}
|
||||
|
||||
FilesystemNode *FilesystemNode::getRoot() {
|
||||
AbstractFilesystemNode *FilesystemNode::getRoot() {
|
||||
return new PalmOSFilesystemNode();
|
||||
}
|
||||
|
||||
@ -97,9 +96,9 @@ PalmOSFilesystemNode::PalmOSFilesystemNode(const PalmOSFilesystemNode *node) {
|
||||
_path = node->_path;
|
||||
}
|
||||
|
||||
FSList *PalmOSFilesystemNode::listDir(ListMode mode) const {
|
||||
FSList PalmOSFilesystemNode::listDir(ListMode mode) const {
|
||||
|
||||
FSList *myList = new FSList();
|
||||
FSList myList;
|
||||
Err e;
|
||||
Char nameP[256];
|
||||
FileInfoType desc;
|
||||
@ -136,7 +135,7 @@ const char *lastPathComponent(const Common::String &str) {
|
||||
return cur+1;
|
||||
}
|
||||
|
||||
FilesystemNode *PalmOSFilesystemNode::parent() const {
|
||||
AbstractFilesystemNode *PalmOSFilesystemNode::parent() const {
|
||||
|
||||
PalmOSFilesystemNode *p = new PalmOSFilesystemNode();
|
||||
|
||||
|
@ -45,7 +45,7 @@
|
||||
* Implementation of the ScummVM file system API based on POSIX.
|
||||
*/
|
||||
|
||||
class POSIXFilesystemNode : public FilesystemNode {
|
||||
class POSIXFilesystemNode : public AbstractFilesystemNode {
|
||||
protected:
|
||||
String _displayName;
|
||||
bool _isDirectory;
|
||||
@ -62,9 +62,8 @@ public:
|
||||
virtual bool isDirectory() const { return _isDirectory; }
|
||||
virtual String path() const { return _path; }
|
||||
|
||||
virtual FSList *listDir(ListMode mode = kListDirectoriesOnly) const;
|
||||
virtual FilesystemNode *parent() const;
|
||||
virtual FilesystemNode *clone() const { return new POSIXFilesystemNode(this); }
|
||||
virtual FSList listDir(ListMode mode = kListDirectoriesOnly) const;
|
||||
virtual AbstractFilesystemNode *parent() const;
|
||||
};
|
||||
|
||||
|
||||
@ -79,12 +78,12 @@ static const char *lastPathComponent(const Common::String &str) {
|
||||
return cur+1;
|
||||
}
|
||||
|
||||
FilesystemNode *FilesystemNode::getRoot() {
|
||||
AbstractFilesystemNode *FilesystemNode::getRoot() {
|
||||
return new POSIXFilesystemNode();
|
||||
}
|
||||
|
||||
#ifdef MACOSX
|
||||
FilesystemNode *FilesystemNode::getNodeForPath(const String &path) {
|
||||
AbstractFilesystemNode *FilesystemNode::getNodeForPath(const String &path) {
|
||||
return new POSIXFilesystemNode(path);
|
||||
}
|
||||
#endif
|
||||
@ -140,15 +139,16 @@ POSIXFilesystemNode::POSIXFilesystemNode(const POSIXFilesystemNode *node) {
|
||||
_path = node->_path;
|
||||
}
|
||||
|
||||
FSList *POSIXFilesystemNode::listDir(ListMode mode) const {
|
||||
FSList POSIXFilesystemNode::listDir(ListMode mode) const {
|
||||
assert(_isDirectory);
|
||||
DIR *dirp = opendir(_path.c_str());
|
||||
struct stat st;
|
||||
|
||||
struct dirent *dp;
|
||||
FSList *myList = new FSList();
|
||||
FSList myList;
|
||||
|
||||
if (dirp == NULL) return myList;
|
||||
if (dirp == NULL)
|
||||
return myList;
|
||||
|
||||
// ... loop over dir entries using readdir
|
||||
while ((dp = readdir(dirp)) != NULL) {
|
||||
@ -178,13 +178,13 @@ FSList *POSIXFilesystemNode::listDir(ListMode mode) const {
|
||||
|
||||
if (entry._isDirectory)
|
||||
entry._path += "/";
|
||||
myList->push_back(entry);
|
||||
myList.push_back(wrap(new POSIXFilesystemNode(&entry)));
|
||||
}
|
||||
closedir(dirp);
|
||||
return myList;
|
||||
}
|
||||
|
||||
FilesystemNode *POSIXFilesystemNode::parent() const {
|
||||
AbstractFilesystemNode *POSIXFilesystemNode::parent() const {
|
||||
POSIXFilesystemNode *p = new POSIXFilesystemNode();
|
||||
|
||||
// Root node is its own parent. Still we can't just return this
|
||||
|
@ -31,7 +31,7 @@
|
||||
* Implementation of the ScummVM file system API based on Windows API.
|
||||
*/
|
||||
|
||||
class WindowsFilesystemNode : public FilesystemNode {
|
||||
class WindowsFilesystemNode : public AbstractFilesystemNode {
|
||||
protected:
|
||||
String _displayName;
|
||||
bool _isDirectory;
|
||||
@ -49,14 +49,13 @@ public:
|
||||
virtual bool isDirectory() const { return _isDirectory; }
|
||||
virtual String path() const { return _path; }
|
||||
|
||||
virtual FSList *listDir(ListMode) const;
|
||||
virtual FilesystemNode *parent() const;
|
||||
virtual FilesystemNode *clone() const { return new WindowsFilesystemNode(this); }
|
||||
virtual FSList listDir(ListMode) const;
|
||||
virtual AbstractFilesystemNode *parent() const;
|
||||
|
||||
private:
|
||||
static char *toAscii(TCHAR *x);
|
||||
static TCHAR* toUnicode(char *x);
|
||||
static void addFile (FSList* list, ListMode mode, const char *base, WIN32_FIND_DATA* find_data);
|
||||
static void addFile (FSList &list, ListMode mode, const char *base, WIN32_FIND_DATA* find_data);
|
||||
};
|
||||
|
||||
|
||||
@ -82,7 +81,7 @@ TCHAR* WindowsFilesystemNode::toUnicode(char *x) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void WindowsFilesystemNode::addFile(FSList* list, ListMode mode, const char *base, WIN32_FIND_DATA* find_data) {
|
||||
void WindowsFilesystemNode::addFile(FSList &list, ListMode mode, const char *base, WIN32_FIND_DATA* find_data) {
|
||||
WindowsFilesystemNode entry;
|
||||
char *asciiName = toAscii(find_data->cFileName);
|
||||
bool isDirectory;
|
||||
@ -106,10 +105,10 @@ void WindowsFilesystemNode::addFile(FSList* list, ListMode mode, const char *bas
|
||||
entry._isValid = true;
|
||||
entry._isPseudoRoot = false;
|
||||
|
||||
list->push_back(entry);
|
||||
list.push_back(wrap(new WindowsFilesystemNode(&entry)));
|
||||
}
|
||||
|
||||
FilesystemNode *FilesystemNode::getRoot() {
|
||||
AbstractFilesystemNode *FilesystemNode::getRoot() {
|
||||
return new WindowsFilesystemNode();
|
||||
}
|
||||
|
||||
@ -137,10 +136,10 @@ WindowsFilesystemNode::WindowsFilesystemNode(const WindowsFilesystemNode *node)
|
||||
_path = node->_path;
|
||||
}
|
||||
|
||||
FSList *WindowsFilesystemNode::listDir(ListMode mode) const {
|
||||
FSList WindowsFilesystemNode::listDir(ListMode mode) const {
|
||||
assert(_isDirectory);
|
||||
|
||||
FSList *myList = new FSList();
|
||||
FSList myList;
|
||||
|
||||
if (_isPseudoRoot) {
|
||||
#ifndef _WIN32_WCE
|
||||
@ -160,7 +159,7 @@ FSList *WindowsFilesystemNode::listDir(ListMode mode) const {
|
||||
entry._isValid = true;
|
||||
entry._isPseudoRoot = false;
|
||||
entry._path = toAscii(current_drive);
|
||||
myList->push_back(entry);
|
||||
myList.push_back(wrap(new WindowsFilesystemNode(&entry)));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -196,7 +195,7 @@ const char *lastPathComponent(const Common::String &str) {
|
||||
return cur + 1;
|
||||
}
|
||||
|
||||
FilesystemNode *WindowsFilesystemNode::parent() const {
|
||||
AbstractFilesystemNode *WindowsFilesystemNode::parent() const {
|
||||
assert(_isValid || _isPseudoRoot);
|
||||
WindowsFilesystemNode *p = new WindowsFilesystemNode();
|
||||
if (!_isPseudoRoot && _path.size() > 3) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
MODULE := backends
|
||||
|
||||
MODULE_OBJS := \
|
||||
backends/fs/fs.o \
|
||||
backends/fs/posix/posix-fs.o \
|
||||
backends/fs/morphos/abox-fs.o \
|
||||
backends/fs/windows/windows-fs.o \
|
||||
|
@ -34,12 +34,10 @@ namespace GUI {
|
||||
|
||||
BrowserDialog::BrowserDialog(const char *title)
|
||||
: Dialog(20, 10, 320 -2 * 20, 200 - 2 * 10) {
|
||||
_choice = NULL;
|
||||
_titleRef = CFStringCreateWithCString(0, title, CFStringGetSystemEncoding());
|
||||
}
|
||||
|
||||
BrowserDialog::~BrowserDialog() {
|
||||
delete _choice;
|
||||
CFRelease(_titleRef);
|
||||
}
|
||||
|
||||
@ -50,9 +48,7 @@ int BrowserDialog::runModal() {
|
||||
NavUserAction result;
|
||||
NavReplyRecord reply;
|
||||
OSStatus err;
|
||||
|
||||
delete _choice;
|
||||
_choice = 0;
|
||||
bool choiceMade = false;
|
||||
|
||||
// If in fullscreen mode, switch to windowed mode
|
||||
bool wasFullscreen = g_system->getFeatureState(OSystem::kFeatureFullscreenMode);
|
||||
@ -97,7 +93,8 @@ int BrowserDialog::runModal() {
|
||||
err = FSRefMakePath(&ref, (UInt8*)buf, sizeof(buf)-1);
|
||||
assert(err == noErr);
|
||||
|
||||
_choice = FilesystemNode::getNodeForPath(buf);
|
||||
_choice = FilesystemNode(buf);
|
||||
choiceMade = true;
|
||||
}
|
||||
|
||||
err = NavDisposeReply(&reply);
|
||||
@ -110,7 +107,7 @@ int BrowserDialog::runModal() {
|
||||
if (wasFullscreen)
|
||||
g_system->setFeatureState(OSystem::kFeatureFullscreenMode, true);
|
||||
|
||||
return (_choice != 0);
|
||||
return choiceMade;
|
||||
}
|
||||
|
||||
#else
|
||||
@ -127,14 +124,11 @@ enum {
|
||||
};
|
||||
|
||||
BrowserDialog::BrowserDialog(const char *title)
|
||||
: Dialog(20, 10, 320 -2 * 20, 200 - 2 * 10),
|
||||
_node(0), _nodeContent(0) {
|
||||
: Dialog(20, 10, 320 -2 * 20, 200 - 2 * 10)
|
||||
{
|
||||
|
||||
_fileList = NULL;
|
||||
_currentPath = NULL;
|
||||
_node = NULL;
|
||||
_nodeContent = NULL;
|
||||
_choice = NULL;
|
||||
|
||||
// Headline - TODO: should be customizable during creation time
|
||||
new StaticTextWidget(this, 10, 8, _w - 2 * 10, kLineHeight, title, kTextAlignCenter);
|
||||
@ -153,67 +147,41 @@ BrowserDialog::BrowserDialog(const char *title)
|
||||
addButton(_w - (kButtonWidth+10), _h - 24, "Choose", kChooseCmd, 0);
|
||||
}
|
||||
|
||||
BrowserDialog::~BrowserDialog() {
|
||||
delete _node;
|
||||
delete _nodeContent;
|
||||
delete _choice;
|
||||
}
|
||||
|
||||
void BrowserDialog::open() {
|
||||
// If no node has been set, or the last used one is now invalid,
|
||||
// go back to the root/default dir.
|
||||
if (_node == NULL || !_node->isValid()) {
|
||||
delete _node;
|
||||
_node = FilesystemNode::getRoot();
|
||||
assert(_node != NULL);
|
||||
if (!_node.isValid()) {
|
||||
_node = FilesystemNode();
|
||||
}
|
||||
|
||||
// Alway refresh file list
|
||||
updateListing();
|
||||
|
||||
// Nothing chosen by default
|
||||
delete _choice;
|
||||
_choice = 0;
|
||||
|
||||
// Call super implementation
|
||||
Dialog::open();
|
||||
}
|
||||
|
||||
void BrowserDialog::close() {
|
||||
delete _nodeContent;
|
||||
_nodeContent = 0;
|
||||
|
||||
// Call super implementation
|
||||
Dialog::close();
|
||||
}
|
||||
|
||||
void BrowserDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
|
||||
FilesystemNode *tmp;
|
||||
|
||||
switch (cmd) {
|
||||
case kChooseCmd: {
|
||||
// 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].clone();
|
||||
_choice = _nodeContent[selection];
|
||||
} else {
|
||||
_choice = _node->clone();
|
||||
_choice = _node;
|
||||
}
|
||||
setResult(1);
|
||||
close();
|
||||
}
|
||||
break;
|
||||
case kGoUpCmd:
|
||||
tmp = _node->parent();
|
||||
delete _node;
|
||||
_node = tmp;
|
||||
_node = _node.getParent();
|
||||
updateListing();
|
||||
break;
|
||||
case kListItemDoubleClickedCmd:
|
||||
tmp = (*_nodeContent)[data].clone();
|
||||
delete _node;
|
||||
_node = tmp;
|
||||
_node = _nodeContent[data];
|
||||
updateListing();
|
||||
break;
|
||||
default:
|
||||
@ -222,21 +190,17 @@ void BrowserDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data
|
||||
}
|
||||
|
||||
void BrowserDialog::updateListing() {
|
||||
assert(_node != NULL);
|
||||
|
||||
// Update the path display
|
||||
_currentPath->setLabel(_node->path());
|
||||
_currentPath->setLabel(_node.path());
|
||||
|
||||
// Read in the data from the file system
|
||||
delete _nodeContent;
|
||||
_nodeContent = _node->listDir();
|
||||
assert(_nodeContent != NULL);
|
||||
_nodeContent = _node.listDir();
|
||||
|
||||
// Populate the ListWidget
|
||||
Common::StringList list;
|
||||
int size = _nodeContent->size();
|
||||
int size = _nodeContent.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
list.push_back((*_nodeContent)[i].displayName());
|
||||
list.push_back(_nodeContent[i].displayName());
|
||||
}
|
||||
_fileList->setList(list);
|
||||
_fileList->scrollTo(0);
|
||||
|
@ -23,14 +23,12 @@
|
||||
|
||||
#include "gui/dialog.h"
|
||||
#include "common/str.h"
|
||||
#include "backends/fs/fs.h"
|
||||
|
||||
#ifdef MACOSX
|
||||
#include <Carbon/Carbon.h>
|
||||
#endif
|
||||
|
||||
class FilesystemNode;
|
||||
class FSList;
|
||||
|
||||
namespace GUI {
|
||||
|
||||
class ListWidget;
|
||||
@ -41,17 +39,16 @@ class BrowserDialog : public Dialog {
|
||||
typedef Common::StringList StringList;
|
||||
public:
|
||||
BrowserDialog(const char *title);
|
||||
virtual ~BrowserDialog();
|
||||
|
||||
#ifdef MACOSX
|
||||
~BrowserDialog();
|
||||
virtual int runModal();
|
||||
#else
|
||||
virtual void open();
|
||||
virtual void close();
|
||||
virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
|
||||
#endif
|
||||
|
||||
FilesystemNode *getResult() { return _choice; };
|
||||
const FilesystemNode &getResult() { return _choice; };
|
||||
|
||||
|
||||
protected:
|
||||
@ -60,10 +57,10 @@ protected:
|
||||
#else
|
||||
ListWidget *_fileList;
|
||||
StaticTextWidget*_currentPath;
|
||||
FilesystemNode *_node;
|
||||
FSList *_nodeContent;
|
||||
FilesystemNode _node;
|
||||
FSList _nodeContent;
|
||||
#endif
|
||||
FilesystemNode *_choice;
|
||||
FilesystemNode _choice;
|
||||
|
||||
#ifndef MACOSX
|
||||
void updateListing();
|
||||
|
@ -330,15 +330,15 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
|
||||
// Change path for the game
|
||||
case kCmdGameBrowser: {
|
||||
BrowserDialog *_browser = new BrowserDialog("Select additional game directory");
|
||||
if (_browser->runModal() > 0) {
|
||||
// User made his choice...
|
||||
FilesystemNode *dir = _browser->getResult();
|
||||
if (_browser->runModal() > 0) {
|
||||
// User made his choice...
|
||||
FilesystemNode dir(_browser->getResult());
|
||||
|
||||
// TODO: Verify the game can be found in the new directory... Best
|
||||
// done with optional specific gameid to pluginmgr detectgames?
|
||||
// FSList *files = dir->listDir(FilesystemNode::kListFilesOnly);
|
||||
// FSList files = dir.listDir(FilesystemNode::kListFilesOnly);
|
||||
|
||||
_gamePathWidget->setLabel(dir->path());
|
||||
_gamePathWidget->setLabel(dir.path());
|
||||
}
|
||||
draw();
|
||||
break;
|
||||
@ -347,10 +347,10 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
|
||||
// Change path for extra game data (eg, using sword cutscenes when playing via CD)
|
||||
case kCmdExtraBrowser: {
|
||||
BrowserDialog *_browser = new BrowserDialog("Select additional game directory");
|
||||
if (_browser->runModal() > 0) {
|
||||
// User made his choice...
|
||||
FilesystemNode *dir = _browser->getResult();
|
||||
_extraPathWidget->setLabel(dir->path());
|
||||
if (_browser->runModal() > 0) {
|
||||
// User made his choice...
|
||||
FilesystemNode dir(_browser->getResult());
|
||||
_extraPathWidget->setLabel(dir.path());
|
||||
}
|
||||
draw();
|
||||
break;
|
||||
@ -358,10 +358,10 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
|
||||
// Change path for stored save game (perm and temp) data
|
||||
case kCmdSaveBrowser: {
|
||||
BrowserDialog *_browser = new BrowserDialog("Select directory for saved games");
|
||||
if (_browser->runModal() > 0) {
|
||||
// User made his choice...
|
||||
FilesystemNode *dir = _browser->getResult();
|
||||
_savePathWidget->setLabel(dir->path());
|
||||
if (_browser->runModal() > 0) {
|
||||
// User made his choice...
|
||||
FilesystemNode dir(_browser->getResult());
|
||||
_savePathWidget->setLabel(dir.path());
|
||||
}
|
||||
draw();
|
||||
break;
|
||||
@ -505,16 +505,13 @@ void LauncherDialog::addGame() {
|
||||
|
||||
if (_browser->runModal() > 0) {
|
||||
// User made his choice...
|
||||
FilesystemNode *dir = _browser->getResult();
|
||||
FSList *files = dir->listDir(FilesystemNode::kListFilesOnly);
|
||||
FilesystemNode dir(_browser->getResult());
|
||||
FSList files = dir.listDir(FilesystemNode::kListFilesOnly);
|
||||
|
||||
// ...so let's determine a list of candidates, games that
|
||||
// could be contained in the specified directory.
|
||||
DetectedGameList candidates(PluginManager::instance().detectGames(*files));
|
||||
DetectedGameList candidates(PluginManager::instance().detectGames(files));
|
||||
|
||||
delete files;
|
||||
files = 0;
|
||||
|
||||
int idx;
|
||||
if (candidates.isEmpty()) {
|
||||
// No game was found in the specified directory
|
||||
@ -553,7 +550,7 @@ void LauncherDialog::addGame() {
|
||||
ConfMan.set("gameid", result.name, domain);
|
||||
ConfMan.set("description", result.description, domain);
|
||||
}
|
||||
ConfMan.set("path", dir->path(), domain);
|
||||
ConfMan.set("path", dir.path(), domain);
|
||||
|
||||
const bool customLanguage = (result.language != Common::UNK_LANG);
|
||||
const bool customPlatform = (result.platform != Common::kPlatformUnknown);
|
||||
|
@ -476,16 +476,16 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
|
||||
case kChooseSaveDirCmd:
|
||||
if (_browser->runModal() > 0) {
|
||||
// User made his choice...
|
||||
FilesystemNode *dir = _browser->getResult();
|
||||
_savePath->setLabel(dir->path());
|
||||
FilesystemNode dir(_browser->getResult());
|
||||
_savePath->setLabel(dir.path());
|
||||
// TODO - we should check if the directory is writeable before accepting it
|
||||
}
|
||||
break;
|
||||
case kChooseExtraDirCmd:
|
||||
if (_browser->runModal() > 0) {
|
||||
// User made his choice...
|
||||
FilesystemNode *dir = _browser->getResult();
|
||||
_extraPath->setLabel(dir->path());
|
||||
FilesystemNode dir(_browser->getResult());
|
||||
_extraPath->setLabel(dir.path());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user