void OnKeyPressed(object sender, KeyPressedEventArgs e) { // Tab: go to next if (e.Key.VirtualKeyCode == KeyCode.Tab) { var box = (IListBox)e.Control; ++box.Selected; e.Ignore = true; return; } var dialog = (IDialog)sender; //! break keys first var key = new KeyData(e.Key.VirtualKeyCode, e.Key.CtrlAltShift()); myKeyIndex = myKeys.IndexOf(key); if (myKeyIndex >= 0) { if (myHandlers[myKeyIndex] == null) { dialog.Close(); } else { _isKeyHandled = true; Selected = _box.Selected; if (_ii != null && Selected >= 0) { Selected = _ii[Selected]; } var a = new MenuEventArgs((Selected >= 0 ? myItems[Selected] : null)); myHandlers[myKeyIndex](Sender ?? this, a); if (a.Ignore) { e.Ignore = true; return; } dialog.Close(); if (a.Restart) { myKeyIndex = -2; _ii = null; _toFilter = true; } } return; } // CtrlC: copy to clipboard if (e.Key.IsCtrl(KeyCode.C) || e.Key.IsCtrl(KeyCode.Insert)) { var box = (IListBox)e.Control; Far.Api.CopyToClipboard(box.Text); e.Ignore = true; return; } // not incremental? if (IncrementalOptions == 0) { return; } if (key.Is(KeyCode.Backspace) || key.IsShift(KeyCode.Backspace)) { if (_filter.Length == 0) { return; } // case: Shift, drop incremental if (key.IsShift()) { Incremental = string.Empty; _ii = null; myKeyIndex = -2; _toFilter = false; dialog.Close(); return; } if (_filter.Length > Incremental.Length || _filter.Length == Incremental.Length && Incremental.EndsWith("*")) { char c = _filter[_filter.Length - 1]; _filter = _filter.Substring(0, _filter.Length - 1); _re = null; // * and ? if (0 == (IncrementalOptions & PatternOptions.Literal) && (c == '*' || c == '?')) { // update title/bottom GetInfo(out string t, out string b); dialog[0].Text = t; dialog[2].Text = b; } else { _ii = null; _toFilter = true; } } } else { // char or paste var append = string.Empty; if (e.Key.Character > ' ') { append = e.Key.Character.ToString(); } else if (e.Key.IsCtrl(KeyCode.V) || e.Key.IsShift(KeyCode.Insert)) { append = Far.Api.PasteFromClipboard(); } if (append.Length > 0) { // keep and change filter var filterBak = _filter; var reBak = _re; _filter += append; _re = null; // append "*" -> do not close, just update title/bottom if (0 == (IncrementalOptions & PatternOptions.Literal) && append == "*") { GetInfo(out string t, out string b); dialog[0].Text = t; dialog[2].Text = b; return; } // try the filter, rollback on empty var iiBak = _ii; _toFilter = true; MakeFilter(); if (_ii != null && _ii.Count == 0) { _filter = filterBak; _re = reBak; _ii = iiBak; return; } _toFilter = true; } } if (_toFilter) { dialog.Close(); } }