1
0
Fork 0
fgdata/gui/dialogs/file-select.xml
mfranz abdc416f32 - remove "load flight"/"save flight" dialogs, and
- use a file selector instead
- file-select.xml: handle non-existing files correctly
2008-07-11 20:57:52 +00:00

261 lines
6.4 KiB
XML

<?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
Alt-click on ".." enters current working directory
-->
<PropertyList>
<name>file-select</name>
<dialog-name>file-select</dialog-name>
<layout>vbox</layout>
<pref-width>450</pref-width>
<group>
<layout>hbox</layout>
<empty><stretch>1</stretch></empty>
<text>
<label>Select File</label>
</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/>
<input>
<name>dir-input</name>
<pref-width>442</pref-width>
<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>
<list>
<name>list</name>
<halign>fill</halign>
<pref-height>350</pref-height>
<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>
<name>file-input</name>
<pref-width>230</pref-width>
<property>/sim/gui/dialogs/file-select/selection</property>
<live>1</live>
<binding>
<command>dialog-apply</command>
<object-name>file-input</object-name>
</binding>
<binding>
<command>nasal</command>
<script>file_input()</script>
</binding>
</input>
<button>
<legend>OK</legend>
<live>1</live>
<pref-width>200</pref-width>
<default>true</default>
<binding>
<command>dialog-apply</command>
</binding>
<binding>
<command>nasal</command>
<script>ok()</script>
</binding>
<binding>
<command>dialog-close</command>
</binding>
</button>
</group>
<nasal>
<open>
var self = cmdarg();
var list = self.getNode("list");
# cloning
var dlgname = self.getNode("name").getValue();
self.getNode("input/property").setValue("/sim/gui/dialogs/" ~ dlgname ~ "/directory");
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);
var button = dlg.getNode("button", 1);
var dir = dlg.getNode("directory", 1);
var file = dlg.getNode("file", 1);
var path = dlg.getNode("path", 1);
var dotfiles = dlg.getNode("dotfiles", 1);
dotfiles.setBoolValue(dotfiles.getValue());
var kbdctrl = props.globals.getNode("/devices/status/keyboard/ctrl", 1);
var kbdshift = props.globals.getNode("/devices/status/keyboard/shift", 1);
var kbdalt = props.globals.getNode("/devices/status/keyboard/alt", 1);
var current = { dir : "", file : "" };
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;
}
var update = func(d) {
var entries = directory(d);
if (entries == nil) # dir doesn't exist or no permissions
return 0;
var files = [];
var dirs = [];
var hide = !dotfiles.getValue();
foreach (var e; entries) {
if (e == ".") {
append(dirs, e);
continue;
}
if (e == "..") {
if (d != "/")
append(dirs, e);
continue;
}
if (hide and e[0] == `.`)
continue;
var stat = io.stat(d ~ "/" ~ e);
if (stat == nil) # dead link
continue;
if (io.isdir(stat[2]))
append(dirs, e ~ "/");
elsif (!size(pattern) or matches(e))
append(files, e);
}
list.removeChildren("value");
var entries = sort(dirs, cmp) ~ sort(files, cmp);
forindex (var i; entries)
list.getChild("value", i, 1).setValue(entries[i]);
dir.setValue(d);
gui.dialog_update(dlgname, "dir-input", "list");
return 1;
}
var select = func {
var e = selection.getValue();
current.file = "";
var new = nil;
if (e == ".") {
new = current.dir;
if (kbdctrl.getValue())
dotfiles.setBoolValue(!dotfiles.getValue());
} elsif (e == "..") {
if (kbdctrl.getValue())
new = getprop("/sim/fg-root");
elsif (kbdshift.getValue())
new = getprop("/sim/fg-home");
elsif (kbdalt.getValue())
new = getprop("/sim/fg-current");
else
new = current.dir ~ "/..";
} elsif (e[size(e) - 1] == `/`) {
new = current.dir ~ "/" ~ e;
} else {
current.file = e;
gui.dialog_update(dlgname, "file-input");
}
if (new != nil) {
var p = string.fixpath(new);
if (update(p))
current.dir = p;
selection.setValue("");
}
}
var file_input = func {
current.file = selection.getValue();
}
var dir_input = func {
var p = string.fixpath(dir.getValue());
if (update(p))
current.dir = p;
gui.dialog_update(dlgname, "list");
}
var close = func {
call(func { gui.Dialog.instance[dlgname].close() }, nil, var err = []);
}
var ok = func {
dir_input();
file_input();
var p = string.fixpath(current.dir ~ "/" ~ current.file);
var stat = io.stat(p);
path.setValue(stat != nil and io.isdir(stat[2]) ? p ~ "/" : p);
file.setValue(current.file);
close();
}
var op = button.getValue();
if (op == nil or op == "")
op = "OK";
self.getNode("group[1]/button/legend").setValue(op);
var t = title.getValue();
if (t == nil or t == "")
t = "Select File";
self.getNode("group[0]/text/label").setValue(t);
current.dir = (var d = dir.getValue()) != nil and d != "" ? d : getprop("/sim/fg-current");
current.file = (var d = file.getValue()) != nil and d != "" ? d : "";
gui.dialog_update(dlgname, "file-input"); ## dir-input ?
update(string.fixpath(current.dir));
dir.setValue(current.dir);
</open>
</nasal>
</PropertyList>