From 5d9b35510d7d6aad9408e12aaebed2a79e3ed826 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Sat, 20 Nov 2004 21:35:49 +0000 Subject: 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 --- backends/fs/.cvsignore | 1 + backends/fs/fs.cpp | 78 +++++++++++++++++++ backends/fs/fs.h | 150 ++++++++++++++++++------------------- backends/fs/morphos/abox-fs.cpp | 34 +++++---- backends/fs/palmos/palmos-fs.cpp | 21 +++--- backends/fs/posix/posix-fs.cpp | 22 +++--- backends/fs/windows/windows-fs.cpp | 23 +++--- backends/module.mk | 1 + gui/browser.cpp | 68 ++++------------- gui/browser.h | 15 ++-- gui/launcher.cpp | 37 +++++---- gui/options.cpp | 8 +- 12 files changed, 247 insertions(+), 211 deletions(-) create mode 100644 backends/fs/.cvsignore create mode 100644 backends/fs/fs.cpp diff --git a/backends/fs/.cvsignore b/backends/fs/.cvsignore new file mode 100644 index 0000000000..39a06683b7 --- /dev/null +++ b/backends/fs/.cvsignore @@ -0,0 +1 @@ +.deps diff --git a/backends/fs/fs.cpp b/backends/fs/fs.cpp new file mode 100644 index 0000000000..1c9b7efe5d --- /dev/null +++ b/backends/fs/fs.cpp @@ -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; +} diff --git a/backends/fs/fs.h b/backends/fs/fs.h index 2f7e4fa4cd..bc72cccc79 100644 --- a/backends/fs/fs.h +++ b/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 { +}; + /** * 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; - - /** - * The parent node of this directory. - * The parent of the root is the root itself - */ - virtual FilesystemNode *parent() const = 0; + virtual FSList listDir(ListMode mode = kListDirectoriesOnly) 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 { 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; } - }; - - ~FSList() { - for (int i = 0; i < _size; i++) - delete _data[i]; - } + FilesystemNode(); + FilesystemNode(const FilesystemNode &node); +#ifdef MACOSX + FilesystemNode(const String &path); +#endif + ~FilesystemNode(); - 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 &operator =(const FilesystemNode &node); - const FilesystemNode& operator [](int idx) const { - assert(idx >= 0 && idx < _size); - return *_data[idx]; - } + FilesystemNode getParent() const; - int size() const { return _size; } - const_iterator begin() const { - return const_iterator(_data); - } + 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 end() const { - return const_iterator(_data + _size); - } + virtual FSList listDir(ListMode mode = kListDirectoriesOnly) const { return _realNode->listDir(mode); } + +protected: + void decRefCount(); + virtual AbstractFilesystemNode *parent() const { return 0; } }; + #endif diff --git a/backends/fs/morphos/abox-fs.cpp b/backends/fs/morphos/abox-fs.cpp index e535244875..712427b8cc 100644 --- a/backends/fs/morphos/abox-fs.cpp +++ b/backends/fs/morphos/abox-fs.cpp @@ -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); } diff --git a/backends/fs/palmos/palmos-fs.cpp b/backends/fs/palmos/palmos-fs.cpp index 2a5c599e6c..aeecb38d43 100644 --- a/backends/fs/palmos/palmos-fs.cpp +++ b/backends/fs/palmos/palmos-fs.cpp @@ -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(); diff --git a/backends/fs/posix/posix-fs.cpp b/backends/fs/posix/posix-fs.cpp index 86c29910b5..a2f35ad108 100644 --- a/backends/fs/posix/posix-fs.cpp +++ b/backends/fs/posix/posix-fs.cpp @@ -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 diff --git a/backends/fs/windows/windows-fs.cpp b/backends/fs/windows/windows-fs.cpp index 0f6768c099..96231b9a53 100644 --- a/backends/fs/windows/windows-fs.cpp +++ b/backends/fs/windows/windows-fs.cpp @@ -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) { diff --git a/backends/module.mk b/backends/module.mk index 22dfd9c5d2..07201bfca3 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -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 \ diff --git a/gui/browser.cpp b/gui/browser.cpp index 644e41aa90..5755f1fe18 100644 --- a/gui/browser.cpp +++ b/gui/browser.cpp @@ -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); diff --git a/gui/browser.h b/gui/browser.h index 10940fd94c..fcbf8be12d 100644 --- a/gui/browser.h +++ b/gui/browser.h @@ -23,14 +23,12 @@ #include "gui/dialog.h" #include "common/str.h" +#include "backends/fs/fs.h" #ifdef MACOSX #include #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(); diff --git a/gui/launcher.cpp b/gui/launcher.cpp index 23764fda90..130e008f7c 100644 --- a/gui/launcher.cpp +++ b/gui/launcher.cpp @@ -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); diff --git a/gui/options.cpp b/gui/options.cpp index 25a53d62c8..38df8f916f 100644 --- a/gui/options.cpp +++ b/gui/options.cpp @@ -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: -- cgit v1.2.3