Years ago I added code to do this in my personal build. I cleaned up the code, added a GUI and added a TXT option as well as CSV output.
The Preferences dialog for Keyboard sports two new buttons:
The text output looks like:
and the CSV opens in Excel as:
(note–I have sized the columns appropriately above)
Putting each qualifier in a separate column allow one to sort the spreadsheet on multiple columns to easily see which key combos are used/available.
The new code adds the two buttons (if anyone is interested I will post the code but it is very simple) and adds a new wxArrayString (to save additional roundtrips through the name demangler and translation) to srcprefsKeyConfigPrefs.h:
class KeyConfigPrefs:public PrefsPanel
{
[...]
private:
[...]
//efm5 start
void OnPrintText2File(wxCommandEvent & WXevent);
void OnPrintCSV2File(wxCommandEvent & WXevent);
void Print2File(bool pCSV = false);
wxArrayString mLabels;
//efm5 end
[...]
};
mLabels is built in srcprefsKeyConfigPrefs.cpp in the function void KeyConfigPrefs::RepopulateBindingsList():
void KeyConfigPrefs::RepopulateBindingsList()
{
mLabels.Clear();//efm5
[...]
wxString label;
// Labels for undo and redo change according to the last command
// which can be undone/redone, so give them a special check in order
// not to confuse users
if (name == wxT("Undo")) {
label = _("Undo");
}
else if (name == wxT("Redo")) {
label = _("Redo");
}
else {
label = mManager->GetPrefixedLabelFromName(name);
}
label = wxMenuItem::GetLabelFromText(label.BeforeFirst(wxT('t')));
mLabels.Add(label);//efm5
[...]
}
The code which responds to the new buttons may be added at the very end of srcprefsKeyConfigPrefs.cpp and is:
void KeyConfigPrefs::OnPrintText2File(wxCommandEvent & WXUNUSED(WXevent)) {
Print2File();
}
void KeyConfigPrefs::OnPrintCSV2File(wxCommandEvent & WXUNUSED(WXevent)) {
Print2File(true);
}
void KeyConfigPrefs::Print2File(bool pCSV) {
size_t numberOfKeys = mLabels.Count();
size_t numberOfShortcuts = mKeys.Count();
if (numberOfKeys != numberOfShortcuts) {
wxMessageBox(_("Error--the number of items does not equal the number of shortcuts!"));
return;
}
//todo efm5 add default folder to prefs
wxString fileType = wxT(".csv");
if (!pCSV)
fileType = wxT(".txt");
wxString outputFile = wxEmptyString;
wxString outputFolder = wxEmptyString;
wxString previousDirectory = gPrefs->Read(wxT("/Directories/Print2FileDir"), wxEmptyString);
wxFileDialog * filePickerDialog = new wxFileDialog(((wxWindow *)this), _("Output File"), previousDirectory, wxEmptyString, fileType);
if (filePickerDialog) {
if (filePickerDialog->ShowModal() == wxID_OK) {
outputFile = filePickerDialog->GetPath();
wxFileName fileName(outputFile);
outputFolder = fileName.GetPath();
}
delete filePickerDialog;
}
if (!outputFile.IsEmpty()) {
wxFFile textFile(outputFile, wxT("w"));
wxString label(_(","));
if (!pCSV) {
label = (wxT(" "));
label.append(_("SHORTCUT:"));
label.append(wxT(" "));
}
wxString unassigned(_("Unassigned"));
bool wroteOK = false;
size_t wroteNewLine = 0;
for (size_t i = 0; i < numberOfKeys; i++) {
wroteOK = textFile.Write(mLabels.Item(i));
if (wroteOK) wroteOK = textFile.Write(label);
if (wroteOK) {
if (mKeys.Item(i).IsEmpty() && !pCSV)
wroteOK = textFile.Write(unassigned);
else {
if (pCSV) {
wxString extendedKey(wxEmptyString);
bool hasQualifier = false;
if (mKeys.Item(i).Contains(wxT("Alt"))) {
extendedKey.Append(wxT("Alt"));
hasQualifier = true;
}
extendedKey.Append(wxT(","));
if (mKeys.Item(i).Contains(wxT("Ctrl"))) {
extendedKey.Append(wxT("Ctrl"));
hasQualifier = true;
}
extendedKey.Append(wxT(","));
if (mKeys.Item(i).Contains(wxT("Shift"))) {
extendedKey.Append(wxT("Shift"));
hasQualifier = true;
}
extendedKey.Append(wxT(","));
if (hasQualifier)
extendedKey.Append(mKeys.Item(i).AfterLast('+'));
else
extendedKey.Append(mKeys.Item(i));
wroteOK = textFile.Write(extendedKey);
}
else
wroteOK = textFile.Write(mKeys.Item(i));
}
}
if (wroteOK) wroteOK = textFile.Write(wxT("n"));
if (!wroteOK) {
wxMessageBox(_("Write Error--writing shortcuts to file!"));
return;
}
}
gPrefs->Write(wxT("/Directories/Print2FileDir"), outputFolder);
}
}