2007-06-13 21:20:04 +00:00
<?xml version="1.0"?>
<!--
Ctrl-click on "." toggles display of hidden Unix filex (dotfiles)
Ctrl-click on ".." enters $FG_ROOT
Shift-click on ".." enters $FG_HOME
2007-06-17 22:56:22 +00:00
Alt-click on ".." enters current working directory
2007-06-13 21:20:04 +00:00
-->
<PropertyList >
<name > file-select</name>
<dialog-name > file-select</dialog-name>
<layout > vbox</layout>
2009-01-10 21:59:27 +00:00
<resizable > true</resizable>
2007-06-13 21:20:04 +00:00
<pref-width > 450</pref-width>
<group >
<layout > hbox</layout>
2007-06-17 15:27:33 +00:00
<empty > <stretch > 1</stretch> </empty>
2007-06-13 21:20:04 +00:00
<text >
2007-06-17 15:27:33 +00:00
<label > Select File</label>
2007-06-13 21:20:04 +00:00
</text>
<empty > <stretch > 1</stretch> </empty>
<button >
<pref-width > 16</pref-width>
<pref-height > 16</pref-height>
<legend > </legend>
<default > 1</default>
<keynum > 27</keynum>
<border > 2</border>
<binding >
<command > nasal</command>
<script > close()</script>
</binding>
<binding >
<command > dialog-close</command>
</binding>
</button>
</group>
<hrule />
2007-06-17 15:27:33 +00:00
<input >
<name > dir-input</name>
<pref-width > 442</pref-width>
2009-01-10 21:59:27 +00:00
<halign > fill</halign>
2007-06-17 15:27:33 +00:00
<property > /sim/gui/dialogs/file-select/directory</property>
<live > 1</live>
<binding >
<command > dialog-apply</command>
<object-name > dir-input</object-name>
</binding>
<binding >
<command > nasal</command>
<script > dir_input()</script>
</binding>
</input>
2007-06-13 21:20:04 +00:00
<list >
<name > list</name>
<halign > fill</halign>
2009-01-10 21:59:27 +00:00
<valign > fill</valign>
<stretch > true</stretch>
<pref-height > 300</pref-height>
2007-06-13 21:20:04 +00:00
<property > /sim/gui/dialogs/file-select/selection</property>
<binding >
<command > dialog-apply</command>
<object-name > list</object-name>
</binding>
<binding >
<command > nasal</command>
<script > select()</script>
</binding>
</list>
<group >
<layout > hbox</layout>
<input >
2007-06-17 15:27:33 +00:00
<name > file-input</name>
2007-06-14 15:27:49 +00:00
<pref-width > 230</pref-width>
2009-01-10 21:59:27 +00:00
<halign > fill</halign>
<stretch > true</stretch>
2007-06-13 21:20:04 +00:00
<property > /sim/gui/dialogs/file-select/selection</property>
<live > 1</live>
<binding >
<command > dialog-apply</command>
2007-06-17 15:27:33 +00:00
<object-name > file-input</object-name>
2007-06-13 21:20:04 +00:00
</binding>
<binding >
<command > nasal</command>
2007-06-17 15:27:33 +00:00
<script > file_input()</script>
2007-06-13 21:20:04 +00:00
</binding>
2011-08-21 13:00:45 +00:00
<visible >
<equals > <!-- yes, odd condition. easier ways somehow fail,
since we're changing the values with Nasal below... -->
<value > 1</value>
<value > 1</value>
</equals>
</visible>
2007-06-13 21:20:04 +00:00
</input>
<button >
<legend > OK</legend>
<live > 1</live>
2007-06-14 15:27:49 +00:00
<pref-width > 200</pref-width>
2007-06-13 21:20:04 +00:00
<default > true</default>
<binding >
<command > dialog-apply</command>
</binding>
<binding >
<command > nasal</command>
<script > ok()</script>
</binding>
2007-06-14 23:09:01 +00:00
<binding >
<command > dialog-close</command>
</binding>
2007-06-13 21:20:04 +00:00
</button>
</group>
<nasal >
<open >
var self = cmdarg();
var list = self.getNode("list");
2007-06-22 14:13:30 +00:00
# cloning
2007-06-13 21:20:04 +00:00
var dlgname = self.getNode("name").getValue();
2007-06-17 15:27:33 +00:00
self.getNode("input/property").setValue("/sim/gui/dialogs/" ~ dlgname ~ "/directory");
2007-06-13 21:20:04 +00:00
self.getNode("list/property").setValue("/sim/gui/dialogs/" ~ dlgname ~ "/selection");
self.getNode("group[1]/input/property").setValue("/sim/gui/dialogs/" ~ dlgname ~ "/selection");
var dlg = props.globals.getNode("/sim/gui/dialogs/" ~ dlgname, 1);
var selection = dlg.getNode("selection", 1);
var title = dlg.getNode("title", 1);
2007-06-17 15:27:33 +00:00
var button = dlg.getNode("button", 1);
2007-06-13 21:20:04 +00:00
var dir = dlg.getNode("directory", 1);
var file = dlg.getNode("file", 1);
var path = dlg.getNode("path", 1);
2007-06-17 15:27:33 +00:00
var dotfiles = dlg.getNode("dotfiles", 1);
dotfiles.setBoolValue(dotfiles.getValue());
2011-08-21 13:00:45 +00:00
# disable files to show a directory dialog only
self.show_files = dlg.getNode("show-files",1).getValue();
self.getNode("group[1]/input/visible/equals/value").setValue(self.show_files);
2007-06-13 21:20:04 +00:00
var kbdctrl = props.globals.getNode("/devices/status/keyboard/ctrl", 1);
var kbdshift = props.globals.getNode("/devices/status/keyboard/shift", 1);
2007-06-17 22:56:22 +00:00
var kbdalt = props.globals.getNode("/devices/status/keyboard/alt", 1);
2007-06-13 21:20:04 +00:00
var current = { dir : "", file : "" };
2007-06-22 14:13:30 +00:00
var pattern = [];
foreach (var p; dlg.getChildren("pattern"))
append(pattern, p.getValue());
var matches = func(s) {
foreach (var p; pattern)
if (string.match(s, p))
return 1;
return 0;
2007-06-13 21:20:04 +00:00
}
var update = func(d) {
2007-06-14 15:27:49 +00:00
var entries = directory(d);
2016-02-09 23:19:57 +00:00
var retval = 1;
if (entries == nil) { # dir doesn't exist or no permissions
2016-10-09 14:26:15 +00:00
entries = ["..", "Not found or access denied", "Ctrl-click .. for FG_ROOT", "Shift-click .. for FG_HOME","To allow more directories, pass them to --allow-nasal-read"];
2016-02-09 23:19:57 +00:00
retval = 0;
} else {
2007-06-13 21:20:04 +00:00
var files = [];
var dirs = [];
2007-06-17 15:27:33 +00:00
var hide = !dotfiles.getValue();
2007-06-14 15:27:49 +00:00
foreach (var e; entries) {
if (e == ".") {
append(dirs, e);
continue;
}
if (e == "..") {
if (d != "/")
2007-06-13 21:20:04 +00:00
append(dirs, e);
continue;
}
if (hide and e[0] == `.`)
continue;
2007-06-14 15:27:49 +00:00
var stat = io.stat(d ~ "/" ~ e);
2007-06-22 14:13:30 +00:00
if (stat == nil) # dead link
2007-06-13 21:20:04 +00:00
continue;
2009-02-15 18:24:22 +00:00
if (stat[11] == "dir")
2007-06-13 21:20:04 +00:00
append(dirs, e ~ "/");
2011-08-21 13:00:45 +00:00
elsif (self.show_files and (!size(pattern) or matches(e)))
2007-06-13 21:20:04 +00:00
append(files, e);
}
2016-02-09 23:19:57 +00:00
var entries = sort(dirs, cmp) ~ sort(files, cmp);
}
2007-06-14 15:27:49 +00:00
list.removeChildren("value");
2007-06-13 21:20:04 +00:00
forindex (var i; entries)
list.getChild("value", i, 1).setValue(entries[i]);
2007-06-14 15:27:49 +00:00
dir.setValue(d);
2007-06-17 22:56:22 +00:00
gui.dialog_update(dlgname, "dir-input", "list");
2016-02-09 23:19:57 +00:00
return retval;
2007-06-13 21:20:04 +00:00
}
var select = func {
var e = selection.getValue();
current.file = "";
var new = nil;
if (e == ".") {
new = current.dir;
if (kbdctrl.getValue())
2007-06-17 15:27:33 +00:00
dotfiles.setBoolValue(!dotfiles.getValue());
2007-06-13 21:20:04 +00:00
} elsif (e == "..") {
if (kbdctrl.getValue())
2007-06-14 15:27:49 +00:00
new = getprop("/sim/fg-root");
2007-06-13 21:20:04 +00:00
elsif (kbdshift.getValue())
new = getprop("/sim/fg-home");
2007-06-17 22:56:22 +00:00
elsif (kbdalt.getValue())
new = getprop("/sim/fg-current");
2007-06-13 21:20:04 +00:00
else
new = current.dir ~ "/..";
} elsif (e[size(e) - 1] == `/`) {
new = current.dir ~ "/" ~ e;
} else {
current.file = e;
2007-06-17 15:27:33 +00:00
gui.dialog_update(dlgname, "file-input");
2007-06-13 21:20:04 +00:00
}
if (new != nil) {
2008-10-15 16:35:11 +00:00
var p = string.normpath(new);
2007-06-14 15:27:49 +00:00
if (update(p))
current.dir = p;
2007-06-13 21:20:04 +00:00
selection.setValue("");
}
}
2007-06-17 15:27:33 +00:00
var file_input = func {
2007-06-13 21:20:04 +00:00
current.file = selection.getValue();
}
2007-06-17 15:27:33 +00:00
var dir_input = func {
2008-10-15 16:35:11 +00:00
var p = string.normpath(dir.getValue());
2007-06-17 15:27:33 +00:00
if (update(p))
current.dir = p;
gui.dialog_update(dlgname, "list");
}
2007-06-13 21:20:04 +00:00
var close = func {
2007-06-17 15:27:33 +00:00
call(func { gui.Dialog.instance[dlgname].close() }, nil, var err = []);
2007-06-13 21:20:04 +00:00
}
var ok = func {
2007-06-17 15:27:33 +00:00
dir_input();
2011-08-21 13:00:45 +00:00
if (self.show_files)
file_input();
else
current.file = "";
2008-10-15 16:35:11 +00:00
var p = string.normpath(current.dir ~ "/" ~ current.file);
2007-06-14 15:27:49 +00:00
var stat = io.stat(p);
2009-02-15 18:24:22 +00:00
path.setValue(stat != nil and stat[11] == "dir" ? p ~ "/" : p);
2007-06-13 21:20:04 +00:00
file.setValue(current.file);
close();
}
2007-06-17 15:27:33 +00:00
var op = button.getValue();
2007-06-13 21:20:04 +00:00
if (op == nil or op == "")
op = "OK";
self.getNode("group[1]/button/legend").setValue(op);
2007-06-17 15:27:33 +00:00
var t = title.getValue();
if (t == nil or t == "")
2011-08-21 13:00:45 +00:00
{
if (self.show_files)
t = "Select Directory";
else
t = "Select File";
}
2007-06-17 15:27:33 +00:00
self.getNode("group[0]/text/label").setValue(t);
2007-06-17 22:56:22 +00:00
current.dir = (var d = dir.getValue()) != nil and d != "" ? d : getprop("/sim/fg-current");
2007-06-13 21:20:04 +00:00
current.file = (var d = file.getValue()) != nil and d != "" ? d : "";
2007-06-17 15:27:33 +00:00
gui.dialog_update(dlgname, "file-input"); ## dir-input ?
2008-10-15 16:35:11 +00:00
update(string.normpath(current.dir));
2007-06-17 15:27:33 +00:00
dir.setValue(current.dir);
2007-06-13 21:20:04 +00:00
</open>
</nasal>
</PropertyList>