# import module
use Getopt::Long;
-
+use File::Basename;
+use File::Spec;
+
$semicolon = ";"; # help out stupid emacs
$title = "Ardour Shortcuts";
$in_group_def = 0;
$group_number = 0;
%group_names;
%group_text;
+%owner_bindings;
+%group_owners;
%group_bindings;
%modifier_map;
%group_numbering;
if ($platform eq "darwin") {
- $gtk_modifier_map{'PRIMARY'} = 'Primary';
+ $gtk_modifier_map{'PRIMARY'} = 'Primary'; # GTK supports Primary to allow platform-independent binding to the "primary" modifier, which on OS X is Command
$gtk_modifier_map{'SECONDARY'} = 'Control';
$gtk_modifier_map{'TERTIARY'} = 'Shift';
- $gtk_modifier_map{'LEVEL4'} = 'Mod1';
- $gtk_modifier_map{'WINDOW'} = 'Control';
+ $gtk_modifier_map{'LEVEL4'} = 'Mod1';
+
+ # cs_modifier_map == "Cheat Sheet Modifier Map"
+ # Used to control what gets shown in the
+ # cheat sheet for a given (meta)-modifier
$cs_modifier_map{'PRIMARY'} = 'Cmd';
$cs_modifier_map{'SECONDARY'} = 'Control';
$cs_modifier_map{'TERTIARY'} = 'Shift';
- $cs_modifier_map{'LEVEL4'} = 'Mod1';
- $cs_modifier_map{'WINDOW'} = 'Control';
+ $cs_modifier_map{'LEVEL4'} = 'Opt';
+ # used to display what gets shown in the
+ # cheat sheet for mouse bindings. Differs
+ # from cs_modifier map in using shorter
+ # abbreviations.
+
$mouse_modifier_map{'PRIMARY'} = 'Cmd';
$mouse_modifier_map{'SECONDARY'} = 'Ctrl';
$mouse_modifier_map{'TERTIARY'} = 'Shift';
$mouse_modifier_map{'LEVEL4'} = 'Opt';
- $mouse_modifier_map{'WINDOW'} = 'Ctrl';
} else {
$gtk_modifier_map{'PRIMARY'} = 'Control';
$gtk_modifier_map{'SECONDARY'} = 'Alt';
$gtk_modifier_map{'TERTIARY'} = 'Shift';
- $gtk_modifier_map{'LEVEL4'} = 'Meta';
- $gtk_modifier_map{'WINDOW'} = 'Meta';
- $gtk_modifier_map{$winkey} => 'Meta';
+ $gtk_modifier_map{'LEVEL4'} = $winkey; # something like "Mod4><Super"
+
+ # cs_modifier_map == "Cheat Sheet Modifier Map"
+ # Used to control what gets shown in the
+ # cheat sheet for a given (meta)-modifier
$cs_modifier_map{'PRIMARY'} = 'Control';
$cs_modifier_map{'SECONDARY'} = 'Alt';
$cs_modifier_map{'TERTIARY'} = 'Shift';
- $cs_modifier_map{'LEVEL4'} = 'Meta';
- $cs_modifier_map{'WINDOW'} = 'Meta';
- $cs_modifier_map{$winkey} => 'Meta';
+ $cs_modifier_map{'LEVEL4'} = 'Win';
+
+ # used to display what gets shown in the
+ # cheat sheet for mouse bindings. Differs
+ # from cs_modifier map in using shorter
+ # abbreviations.
$mouse_modifier_map{'PRIMARY'} = 'Ctl';
$mouse_modifier_map{'SECONDARY'} = 'Alt';
$mouse_modifier_map{'TERTIARY'} = 'Shift';
- $mouse_modifier_map{'LEVEL4'} = 'Meta';
- $mouse_modifier_map{'WINDOW'} = 'Meta';
- $mouse_modifier_map{$winkey} => 'Meta';
+ $mouse_modifier_map{'LEVEL4'} = 'Win';
}
%keycodes = ();
}
if ($make_accelmap && !$merge_from) {
- print ";; this accelmap was produced by tools/fmt-bindings\n";
+ print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
}
-while (<>) {
+$bindings_name = basename ($ARGV[0]);
+$bindings_name =~ s/.bindings\.in$//;
+
+open SOURCE, "<", $ARGV[0] or die $!;
+
+while (<SOURCE>) {
next if /^$semicolon/;
if (/^\$/) {
s/^%//;
chop;
- ($group_key,$group_name) = split (/\s+/, $_, 2);
+ ($group_key,$owner,$group_name) = split (/\s+/, $_, 3);
+ if ($make_accelmap) {
+ if (!exists ($owner_bindings{$owner})) {
+ $owner_bindings{$owner} = [ [] ];
+ }
+ $group_owners{$group_key} = $owner;
+ }
$group_number++;
$group_text = "";
$in_group_def = 1;
chop;
($key,$action,$binding,$text) = split (/\|/, $_, 4);
+ $gkey = $key;
+ $gkey =~ s/^-//;
+ $owner = $group_owners{$gkey};
+
# substitute bindings
$gtk_binding = $binding;
# remove + and don't print it in the accelmap
$key =~ s/^\+//;
} else {
- # include this in the accelmap
- if (!$merge_from && $make_accelmap) {
- foreach $k (keys %gtk_modifier_map) {
- $gtk_binding =~ s/\@$k\@/$gtk_modifier_map{$k}/;
- }
- print "(gtk_accel_path \"<Actions>/$action\" \"$gtk_binding\")\n";
+ # include this in the accelmap if it is part of a group that has an "owner"
+ if (!$merge_from && $make_accelmap && exists ($owner_bindings{$owner})) {
+
+ $b = $binding;
+ $b =~ s/<@//g;
+ $b =~ s/@>//g;
+ $b =~ s/PRIMARY/Primary-/;
+ $b =~ s/SECONDARY/Secondary-/;
+ $b =~ s/TERTIARY/Tertiary-/;
+ $b =~ s/LEVEL4/Level4-/;
+
+ $bref = $owner_bindings{$owner};
+ push (@$bref, [ $action, $b ]);
}
}
next;
}
+if ($make_accelmap) {
+ print "<BindingSet name=\"" . $bindings_name . "\">\n";
+
+ foreach $owner (keys %owner_bindings) {
+ print " <Bindings name=\"$owner\">\n <Press>\n";
+ $bindings = $owner_bindings{$owner};
+ shift (@$bindings); # remove initial empty element
+ for my $binding (@$bindings) {
+ print ' <Binding key="' . @$binding[1] . '" action="' . @$binding[0] . "\"/>\n";
+ }
+ print " </Press>\n </Bindings>\n";
+ }
+
+ # merge in the "fixed" bindings that are not defined by the argument given to this program
+ # namely, the step editor and the mixer windows
+
+ foreach $hardcoded_bindings ("mixer.bindings", "step_editing.bindings", "monitor.bindings", "processor_box.bindings") {
+ $path = File::Spec->catfile (dirname ($ARGV[0]), $hardcoded_bindings);
+ open HARDCODED, "<", $path or die $!;
+ while (<HARDCODED>) {
+ print $_;
+ }
+ close HARDCODED;
+ }
+
+ print "</BindingSet>\n";
+}
+
if ($make_accelmap || !$make_cheatsheet) {
exit 0;
}