mirror of https://github.com/stella-emu/stella.git
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:
parent
f271830ed4
commit
3aed9378a8
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 |
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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:
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue