Updated filename handling so that paths saved to the config files and

shown within the UI use the '~' symbol whenever possible.  This means
that paths from the settings file are now truly relative; change your
home directory, and the settings file will still work (it no longer
contains absolute path names).


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1776 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2009-06-18 13:07:51 +00:00
parent f271830ed4
commit 3aed9378a8
12 changed files with 98 additions and 16 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -559,10 +559,14 @@
but for Windows it means your 'My Documents' folder.</p> but for Windows it means your 'My Documents' folder.</p>
<p>Selecting a new path for an item is done by clicking the appropriate button(s) <p>Selecting a new path for an item is done by clicking the appropriate button(s)
(in this case, 'Rom path' was selected). Note that although the rom path (in this case, 'Rom path' was selected), which will show a browser as follows:</p>
was '~/src/stella', it expands to '/home/stephena/src/stella' in the browser:</p>
<p><img src="graphics/rom_browser.png"></p> <p><img src="graphics/rom_browser.png"></p>
<p>The browser should be self-explanatory. The 'Go Up' button moves to the parent
folder (if it exists), and the 'Base Dir' button moves to the base directory where,
by default, all Stella-related files are stored. Click 'Choose' to select an item,
or 'Cancel' to exit the browser.</p>
<p>Once you've changed your settings, you can start emulation by selecting a ROM <p>Once you've changed your settings, you can start emulation by selecting a ROM
and pressing 'Enter' or clicking 'Select', or double-clicking a ROM. Note that and pressing 'Enter' or clicking 'Select', or double-clicking a ROM. Note that
some games require you to 'Reset' the console before you start playing. In this some games require you to 'Reset' the console before you start playing. In this

View File

@ -129,6 +129,13 @@ string FilesystemNode::getPath() const
return _realNode->getPath(); return _realNode->getPath();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string FilesystemNode::getRelativePath() const
{
assert(_realNode);
return _realNode->getRelativePath();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FilesystemNode::isDirectory() const bool FilesystemNode::isDirectory() const
{ {

View File

@ -165,8 +165,7 @@ class FilesystemNode
virtual string getName() const; virtual string getName() const;
/** /**
* Return a string representation of the file which can be passed to fopen(), * Return a string representation of the file which can be passed to fopen().
* and is suitable for archiving (i.e. writing to the config file).
* This will usually be a 'path' (hence the name of the method), but can * This will usually be a 'path' (hence the name of the method), but can
* be anything that fulfills the above criterions. * be anything that fulfills the above criterions.
* *
@ -177,6 +176,18 @@ class FilesystemNode
*/ */
virtual string getPath() const; virtual string getPath() const;
/**
* Return a string representation of the file which contains the '~'
* symbol (if applicable), and is suitable for archiving (i.e. writing
* to the config file).
*
* @note Do not assume that this string contains (back)slashes or any
* other kind of 'path separators'.
*
* @return the 'path' represented by this filesystem node
*/
virtual string getRelativePath() const;
/** /**
* Determine whether this node has a parent. * Determine whether this node has a parent.
*/ */
@ -294,6 +305,11 @@ class AbstractFilesystemNode
*/ */
virtual string getPath() const = 0; virtual string getPath() const = 0;
/**
* Returns the 'path' of the current node, containing '~' and for archiving.
*/
virtual string getRelativePath() const = 0;
/** /**
* Indicates whether this path refers to a directory or not. * Indicates whether this path refers to a directory or not.
*/ */

View File

@ -81,6 +81,11 @@ BrowserDialog::BrowserDialog(GuiObject* boss, const GUI::Font& font)
buttonWidth, buttonHeight, "Go up", kGoUpCmd); buttonWidth, buttonHeight, "Go up", kGoUpCmd);
addFocusWidget(_goUpButton); addFocusWidget(_goUpButton);
_basedirButton =
new ButtonWidget(this, font, 15 + buttonWidth, _h - buttonHeight - 10,
buttonWidth, buttonHeight, "Base Dir", kBaseDirCmd);
addFocusWidget(_basedirButton);
#ifndef MAC_OSX #ifndef MAC_OSX
b = new ButtonWidget(this, font, _w - 2 * (buttonWidth + 7), _h - buttonHeight - 10, b = new ButtonWidget(this, font, _w - 2 * (buttonWidth + 7), _h - buttonHeight - 10,
buttonWidth, buttonHeight, "Choose", kChooseCmd); buttonWidth, buttonHeight, "Choose", kChooseCmd);
@ -157,7 +162,7 @@ void BrowserDialog::updateListing()
_nodeList->clear(); _nodeList->clear();
// Update the path display // Update the path display
_currentPath->setLabel(_node.getPath()); _currentPath->setLabel(_node.getRelativePath());
// Read in the data from the file system // Read in the data from the file system
FSList content; FSList content;
@ -210,6 +215,11 @@ void BrowserDialog::handleCommand(CommandSender* sender, int cmd,
updateListing(); updateListing();
break; break;
case kBaseDirCmd:
_node = FilesystemNode(instance().baseDir(false));
updateListing();
break;
case kListItemActivatedCmd: case kListItemActivatedCmd:
case kListItemDoubleClickedCmd: case kListItemDoubleClickedCmd:
{ {

View File

@ -51,8 +51,9 @@ class BrowserDialog : public Dialog, public CommandSender
private: private:
enum { enum {
kChooseCmd = 'CHOS', kChooseCmd = 'CHOS',
kGoUpCmd = 'GOUP' kGoUpCmd = 'GOUP',
kBaseDirCmd = 'BADR'
}; };
int _cmd; int _cmd;
@ -61,6 +62,7 @@ class BrowserDialog : public Dialog, public CommandSender
StaticTextWidget* _currentPath; StaticTextWidget* _currentPath;
StaticTextWidget* _title; StaticTextWidget* _title;
ButtonWidget* _goUpButton; ButtonWidget* _goUpButton;
ButtonWidget* _basedirButton;
FilesystemNode _node; FilesystemNode _node;
GameList* _nodeList; GameList* _nodeList;

View File

@ -273,49 +273,49 @@ void FileSnapDialog::handleCommand(CommandSender* sender, int cmd,
case kRomDirChosenCmd: case kRomDirChosenCmd:
{ {
FilesystemNode dir(myBrowser->getResult()); FilesystemNode dir(myBrowser->getResult());
myRomPath->setEditString(dir.getPath()); myRomPath->setEditString(dir.getRelativePath());
break; break;
} }
case kStateDirChosenCmd: case kStateDirChosenCmd:
{ {
FilesystemNode dir(myBrowser->getResult()); FilesystemNode dir(myBrowser->getResult());
myStatePath->setEditString(dir.getPath()); myStatePath->setEditString(dir.getRelativePath());
break; break;
} }
case kCheatFileChosenCmd: case kCheatFileChosenCmd:
{ {
FilesystemNode dir(myBrowser->getResult()); FilesystemNode dir(myBrowser->getResult());
myCheatFile->setEditString(dir.getPath()); myCheatFile->setEditString(dir.getRelativePath());
break; break;
} }
case kPaletteFileChosenCmd: case kPaletteFileChosenCmd:
{ {
FilesystemNode dir(myBrowser->getResult()); FilesystemNode dir(myBrowser->getResult());
myPaletteFile->setEditString(dir.getPath()); myPaletteFile->setEditString(dir.getRelativePath());
break; break;
} }
case kPropsFileChosenCmd: case kPropsFileChosenCmd:
{ {
FilesystemNode dir(myBrowser->getResult()); FilesystemNode dir(myBrowser->getResult());
myPropsFile->setEditString(dir.getPath()); myPropsFile->setEditString(dir.getRelativePath());
break; break;
} }
case kSnapDirChosenCmd: case kSnapDirChosenCmd:
{ {
FilesystemNode dir(myBrowser->getResult()); FilesystemNode dir(myBrowser->getResult());
mySnapPath->setEditString(dir.getPath()); mySnapPath->setEditString(dir.getRelativePath());
break; break;
} }
case kEEPROMDirChosenCmd: case kEEPROMDirChosenCmd:
{ {
FilesystemNode dir(myBrowser->getResult()); FilesystemNode dir(myBrowser->getResult());
myEEPROMPath->setEditString(dir.getPath()); myEEPROMPath->setEditString(dir.getRelativePath());
break; break;
} }

View File

@ -266,7 +266,7 @@ void LauncherDialog::updateListing()
myPrevDirButton->setEnabled(myCurrentNode.hasParent()); myPrevDirButton->setEnabled(myCurrentNode.hasParent());
// Show current directory // Show current directory
myDir->setLabel(myCurrentNode.getPath()); myDir->setLabel(myCurrentNode.getRelativePath());
// Now fill the list widget with the contents of the GameList // Now fill the list widget with the contents of the GameList
StringList l; StringList l;

View File

@ -61,6 +61,7 @@ class POSIXFilesystemNode : public AbstractFilesystemNode
virtual string getDisplayName() const { return _displayName; } virtual string getDisplayName() const { return _displayName; }
virtual string getName() const { return _displayName; } virtual string getName() const { return _displayName; }
virtual string getPath() const { return _path; } virtual string getPath() const { return _path; }
virtual string getRelativePath() const;
virtual bool isDirectory() const { return _isDirectory; } virtual bool isDirectory() const { return _isDirectory; }
virtual bool isReadable() const { return access(_path.c_str(), R_OK) == 0; } virtual bool isReadable() const { return access(_path.c_str(), R_OK) == 0; }
virtual bool isWritable() const { return access(_path.c_str(), W_OK) == 0; } virtual bool isWritable() const { return access(_path.c_str(), W_OK) == 0; }
@ -135,7 +136,7 @@ POSIXFilesystemNode::POSIXFilesystemNode(const string& p, bool verify)
if (home != NULL && strlen(home) < MAXPATHLEN) if (home != NULL && strlen(home) < MAXPATHLEN)
{ {
_path = home; _path = home;
// Skip over the tilda. We know that p contains at least // Skip over the tilde. We know that p contains at least
// two chars, so this is safe: // two chars, so this is safe:
_path += p.c_str() + 1; _path += p.c_str() + 1;
} }
@ -162,6 +163,26 @@ POSIXFilesystemNode::POSIXFilesystemNode(const string& p, bool verify)
setFlags(); setFlags();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string POSIXFilesystemNode::getRelativePath() const
{
// If the path starts with the home directory, replace it with '~'
const char* home = getenv("HOME");
if(home != NULL)
{
int len = strlen(home);
if(strncmp(_path.c_str(), home, len) == 0)
{
string path = "~";
const char* offset = _path.c_str() + len;
if(*offset != '/') path += "/";
path += offset;
return path;
}
}
return _path;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool POSIXFilesystemNode::getChildren(AbstractFSList& myList, ListMode mode, bool POSIXFilesystemNode::getChildren(AbstractFSList& myList, ListMode mode,
bool hidden) const bool hidden) const

View File

@ -139,6 +139,7 @@ class WindowsFilesystemNode : public AbstractFilesystemNode
virtual string getDisplayName() const { return _displayName; } virtual string getDisplayName() const { return _displayName; }
virtual string getName() const { return _displayName; } virtual string getName() const { return _displayName; }
virtual string getPath() const { return _path; } virtual string getPath() const { return _path; }
virtual string getRelativePath() const;
virtual bool isDirectory() const { return _isDirectory; } virtual bool isDirectory() const { return _isDirectory; }
virtual bool isReadable() const { return _access(_path.c_str(), R_OK) == 0; } virtual bool isReadable() const { return _access(_path.c_str(), R_OK) == 0; }
virtual bool isWritable() const { return _access(_path.c_str(), W_OK) == 0; } virtual bool isWritable() const { return _access(_path.c_str(), W_OK) == 0; }
@ -328,6 +329,27 @@ WindowsFilesystemNode::WindowsFilesystemNode(const string& p)
_isPseudoRoot = false; _isPseudoRoot = false;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string WindowsFilesystemNode::getRelativePath() const
{
// If the path starts with the home directory, replace it with '~'
const string& home = myDocsFinder.getPath();
if(home != "")
{
// Windows file system not case sensitive
int len = home.length();
if(BSPF_strncasecmp(home.c_str(), _path.substr(0, len).c_str()) == 0)
{
string path = "~";
const char* offset = _path.c_str() + len;
if(*offset != '\\') path += '\\';
path += offset;
return path;
}
}
return _path;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool WindowsFilesystemNode:: bool WindowsFilesystemNode::
getChildren(AbstractFSList& myList, ListMode mode, bool hidden) const getChildren(AbstractFSList& myList, ListMode mode, bool hidden) const