1
0
Fork 0
fgdata/gui/dialogs/file-select.xml
mfranz f827653668 - create new Nasal module string.nas with simple shell style pattern matching
algorithm (needed for the file selector and useful for other purposes, like
  assembling lists of livery or screenshot files etc.)
- io.nas: move fixpath to string.nas (it's not only useful for file paths
  but can also be used for property paths)
- screen.nas: move trim to string.nas (used by screen.nas and nasal-console.xml)
- gui.nas: add pattern matching to FileSelctor
- ufo.nas: use patterm matching (only *.ac and *.xml files shall be listed)
2007-06-22 14:13:30 +00:00

263 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);
if (stat == nil)
return;
path.setValue(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>