// qt_xcmd.cpp -- extended command widget
//
// TODO:
-// Add button that toggles the grid of command names from column-oriented
-// to row-oriented and vice versa.
-// Add another button to filter out commands that can be invoked by a
-// 'normal' keystroke (not Meta) with current key bindings.
-// If not those, move the [cancel] button from being absurdly wide at the
-// top of the popup to being ordinary width, right justified on same
-// line as the prompt where user's typed characters are shown.
+// Maybe extend filtering to be able to omit commands that can be invoked
+// by a 'normal' keystroke (not Meta) with current key bindings, or to
+// exclude commands which don't autocomplete to match '#?'.
+// Either disable [Layout] when prompt has a partial response, or
+// preserve that partial response across widget tear-down/rebuild.
+// Maybe make the number of grid columns user settable? Or a way to
+// specify a different font (smaller might be necessary for some folks;
+// the font set up in "Qt settings" or "Preferences" applies to the
+// message and status windows but not to extended command choosing).
+//
+
+//
+// Widget appearance (excluding window title bar):
+// +----------------------------------------------------+
+// | [Cancel] [Filter] [Layout] [Reset] | control buttons
+// |# Extended commands | text entry & title
+// +----------------------------------------------------+
+// | [cmmnd_1] [cmnd_14] ... [cmnd_92] [cmd_105] | boxed grid of...
+// | [cmmnd_2] [cmnd_15] ... [cmnd_93] [cmd_106] | ...command buttons
+// ...
+// | [cmnd_13] [cmnd_26] ... [cmd_104] blank |
+// +----------------------------------------------------+
+//
+// Typed input gets appended to "#". When enough to be unambiguous has
+// accumulated, the matching command is immediately chosen (except for
+// the prefix special case mentioned for [Cancel]);
+// Title is centered and describes which [sub]set of commands are shown.
+// It shares the prompt line to conserve vertical space.
+// [Cancel] is highlighted as the default and applies if <return> is typed,
+// with special handling when player has typed up to the end of one
+// command which is a prefix of another; there, <return> or <space> is
+// used to select the shorter while still providing opportunity to type
+// more of the longer command; (there are several such cases:
+// "#drop[type]", "#known[class]", "#takeoff[all]", "#version[short]");
+// button is left justitied (prior to addition of the filter/layout/reset
+// buttons, [Cancel] stretched all the way across the top of the widget);
+// [Filter] is grayed out when outside wizard mode; when in wizard mode,
+// it cycles through "all commands", "normal mode commands only", and
+// "wizard mode extra commands only"; [if it ever gets extended to do
+// anything in normal play, it will need a more substantial interface
+// than repeated clicks but those seem adequate for present wizard
+// mode-only usage];
+// [Layout] toggles between displaying the command buttons down columns
+// (as shown above) versus across rows ([cmd_1][cmd_2]...[cmd_9], &c);
+// [Reset] clears typed partial response, if any, and sets filtering back
+// to "all commands" and/or toggles layout back to by-column if either
+// of those differ from their defaults;
+// [cmd_N] are buttons labelled with command names; clicking returns the
+// index for the name.
+//
+// Changing filter or layout returns 0 to caller who then calls us again
+// (current filter and layout are kept in qt_settings so persist);
+// much simpler than reorganizing the button grid's contents on the fly.
+// [TODO: perform '0 => retry' handling in qt_get_ext_cmd() rather than
+// relying on the core to maintain that behavior.]
+// Current grid size with SHELL and SUSPEND enabled is 13x9 for all
+// commands, 13x7 for normal mode commands, and 7x4 (when by-column) or
+// 4x7 (if by-row) for wizard mode commands. Column counts are hardcoded
+// and row counts are adjusted to fit (the command list, not the screen).
+// Maybe move prompt and title above control buttons? However, menus have
+// their count entry feedback positioned between control buttons and the
+// rest of the information--current layout matches that.
+// The popup is displayed as full-fledged window but the window title bar
+// is blank (at least on OSX).
+// If clicking on [Filter] or [Layout] (or [Reset], but there isn't any
+// particular reason to try to run it twice in a row) places the pointer
+// inside any button, clicking again won't do anything unless the pointer
+// is moved (again, at least on OSX); a single pixel probably suffices.
+// Possibly because despite not moving it has effectively gone into a
+// whole new window since the old one gets torn down and is replaced by
+// a new one that uses revised filter or layout settings.
+//
extern "C" {
#include "hack.h"
#include "qt_set.h"
#include "qt_str.h"
+// temporary
+extern int qt_compact_mode;
+// end temporary
+
namespace nethack_qt_ {
+/* 'wizard' is #undef'd above (now in qt_pre.h) because a Qt header uses
+ that token, so create our own based on knowledge of 'wizard's internals */
+#define WizardMode (::flags.debug)
+
extern uchar keyValue(QKeyEvent *key_event); // from qt_menu.cpp
// temporary
// end temporary
static inline bool
-interesting_command(unsigned indx)
+interesting_command(unsigned indx, int cmds)
{
- return (!(extcmdlist[indx].flags & CMD_NOT_AVAILABLE)
- /* 'wizard' is #undef'd above because Qt uses that token
- so rely on its internals */
- && (flags.debug || !(extcmdlist[indx].flags & WIZMODECMD)));
+ if (!WizardMode)
+ cmds = normal_cmds;
+
+ // entry 0 is a no-op; don't bother displaying it in the command grid
+ if (indx == 0 && !strcmp("#", extcmdlist[indx].ef_txt))
+ return false;
+ // some commands might have been compiled-out; don't show them
+ if ((extcmdlist[indx].flags & CMD_NOT_AVAILABLE) != 0)
+ return false;
+ // if picking from normal mode-only don't show wizard mode commands
+ // or if picking from wizard mode-only don't show normal commands
+ if ((cmds == normal_cmds && (extcmdlist[indx].flags & WIZMODECMD) != 0)
+ || (cmds == wizard_cmds && (extcmdlist[indx].flags & WIZMODECMD) == 0))
+ return false;
+ // if we've gotten here, this command isn't filtered away, so show it
+ return true;
}
NetHackQtExtCmdRequestor::NetHackQtExtCmdRequestor(QWidget *parent) :
- QDialog(parent)
+ QDialog(parent),
+ prompt(new QLabel("#", this)),
+ cancel_btn(new QPushButton("Cancel", this)),
+ byRow(qt_settings->xcmd_by_row),
+ set(qt_settings->xcmd_set),
+ butoffset(0),
+ exactmatchindx(xcmdNoMatch)
{
- QVBoxLayout *l = new QVBoxLayout(this);
+ if (!WizardMode)
+ set = normal_cmds; // {all,wizard}_cmds are wizard mode only
+
+ QVBoxLayout *xl = new QVBoxLayout(this); // overall xcmd layout
+ int butw = 50; // initial button width; will be increased if too small
+ // should probably use the qt_settings font size as a spacing hint;
+ // tiny font, tiny internal margins; small font, small margins;
+ // medium or bigger, default margins (9 or 11?)
+ int spacing = qt_compact_mode ? 3 : -1; // 0 would abut; -1 gives default
+
+ // first, the popup's controls: a row of buttons along the top;
+ // the two padding widgets make the control buttons line up better
+ // with the grid of xcmd choice buttons (closer but not exactly)
+ QHBoxLayout *ctrls = new QHBoxLayout();
+ ctrls->setSpacing(spacing); // only seems to affect horizontal, not vert.
+ ctrls->addWidget(new QLabel(" ")); // padding
+ // Cancel, created during constructor setup (accessed in other routines)
+ DefaultActionIsCancel(true); /* cancel_btn->setDefault(true); */
+ cancel_btn->setMinimumSize(cancel_btn->sizeHint());
+ butw = std::max(butw, cancel_btn->width());
+ ctrls->addWidget(cancel_btn);
+ ctrls->addStretch(0); // Cancel will be left justified, others far right
+ // Filter: change the [sub]set of commands that get shown;
+ // presently only useful when running in wizard mode
+ QPushButton *filter_btn = new QPushButton("Filter", this);
+ if (!WizardMode) { // nothing to filter if not in wizard mode
+ filter_btn->setEnabled(false); // gray the [Filter] button out
+#if 0 /* This works but makes [Reset] seem to be redundant. */
+ // graying out may not be adequate; conceal [Filter] so that
+ // players without access to wizard mode won't become concerned
+ // about something that seems to them to always be disabled
+ filter_btn->hide();
+#endif
+ }
+ filter_btn->setMinimumSize(filter_btn->sizeHint());
+ butw = std::max(butw, filter_btn->width());
+ ctrls->addWidget(filter_btn);
+ // Layout: switch from by-column grid to by-row grid or vice versa
+ QPushButton *layout_btn = new QPushButton("Layout", this);
+ layout_btn->setMinimumSize(layout_btn->sizeHint());
+ butw = std::max(butw, layout_btn->width());
+ ctrls->addWidget(layout_btn);
+ // Reset: switch filter back to all commands and layout back to by-column
+ QPushButton *reset__btn = new QPushButton("Reset", this);
+ reset__btn->setMinimumSize(reset__btn->sizeHint());
+ butw = std::max(butw, reset__btn->width());
+ ctrls->addWidget(reset__btn);
+ ctrls->addWidget(new QLabel(" ")); // padding
+ xl->addLayout(ctrls);
- QPushButton *can = new QPushButton("Cancel", this);
- can->setDefault(true);
- can->setMinimumSize(can->sizeHint());
- l->addWidget(can);
+ // text entry takes place below the row of control buttons and above
+ // the grid of command buttons; show typed text in fixed-width font
+ prompt->setFont(qt_settings->normalFixedFont());
- prompt = new QLabel("#", this);
- l->addWidget(prompt);
+ // grid title rather than overall popup title
+ const char *ctitle = ((set == all_cmds)
+ ? "All extended commands"
+ : (set == normal_cmds)
+ ? (WizardMode ? "Normal mode extended commands"
+ : "Extended commands")
+ : (set == wizard_cmds)
+ ? "Debug mode extended commands"
+ : "(unknown)"); // won't happen
+ const QString &qtitle = QString(ctitle);
+ // rectangular grid to hold a button for each extended command name
+ QGroupBox *grid = new QGroupBox(); /* new QGroupBox(title, this); */
+ // used to connect the buttons with their click handling routine
+ QButtonGroup *group = new QButtonGroup(this);
- QButtonGroup *group=new QButtonGroup(this);
- QGroupBox *grid=new QGroupBox("Extended commands",this);
- l->addWidget(grid);
+ // put grid title on same line as prompt (the padding simplifies centering)
+ QHBoxLayout *pl = new QHBoxLayout(); // prompt line
+ pl->addWidget(prompt);
+ QLabel *tt = new QLabel(qtitle);
+ tt->setAlignment(Qt::AlignHCenter); // center title horizontally
+ pl->addWidget(tt);
+ pl->addWidget(new QLabel(" ")); // padding to balance prompt
+ xl->addLayout(pl);
+ xl->addWidget(grid);
+
+ // having the controls in the same button group as the extended command
+ // choices means that they use the same click callback [a holdover from
+ // when Cancel was the only one; using a separate group and separate
+ // click callback would eliminate the need for butoffset in Button()]
+ group->addButton(cancel_btn, butoffset), ++butoffset; // (,0), 1
+ group->addButton(filter_btn, butoffset), ++butoffset; // (,1), 2
+ group->addButton(layout_btn, butoffset), ++butoffset; // (,2), 3
+ group->addButton(reset__btn, butoffset), ++butoffset; // (,3), 4
unsigned i, j, ncmds = 0;
- int butw = 50;
QFontMetrics fm = fontMetrics();
+ // count the number of commands in current [sub]set and find the size of
+ // the widest choice button; starting size is from widest control button
for (i = 0; extcmdlist[i].ef_txt; ++i) {
- if (interesting_command(i)) {
+ if (interesting_command(i, set)) {
++ncmds;
butw = std::max(butw, 30 + fm.width(extcmdlist[i].ef_txt));
}
}
+ // if any of the choice buttons were bigger than the control buttons,
+ // make the control buttons bigger to match
+ if (cancel_btn->width() < butw)
+ cancel_btn->setMinimumWidth(butw);
+ if (filter_btn->width() < butw)
+ filter_btn->setMinimumWidth(butw);
+ if (layout_btn->width() < butw)
+ layout_btn->setMinimumWidth(butw);
+ if (reset__btn->width() < butw)
+ reset__btn->setMinimumWidth(butw);
- /* 'ncols' should be calculated to fit (or enable a vertical scrollbar
+ QVBoxLayout *bl = new QVBoxLayout(grid);
+ QGridLayout *gl = new QGridLayout();
+ // for qt_compact_mode, put buttons closer together
+ gl->setSpacing(spacing);
+ bl->addLayout(gl);
+ // could grow the buttons[] vector one element at a time but since we
+ // know the ultimate size, grow to that in one operation
+ buttons.resize((int) ncmds);
+
+ /* 'ncols' could be calculated to fit (or enable a vertical scrollbar
when resulting 'nrows' is too big, if GroupBox supports that);
it used to be hardcoded 4 but after every command became accessible
as an extended command, that resulted in so many rows that some of
- the buttons were chopped off at the bottom of the grid */
- unsigned ncols = !flags.debug ? 6 : 8,
- nrows = (ncmds + ncols - 1) / ncols;
+ the grid was chopped off at the bottom of the screen and the buttons
+ in that portion were out of reach */
+ unsigned ncols = (set == all_cmds) ? 9
+ : (set == normal_cmds) ? 7
+ : (set == wizard_cmds) ? (byRow ? 7 : 4)
+ : 1; // can't happen
+ unsigned nrows = (ncmds + ncols - 1) / ncols;
/*
- * Choose grid layout. This ought to selected via a button that can
- * be used to toggle the setting back and forth.
- *
- * by row vs by column
- * a b a e
- * c d b f
- * e f c g
- * g d
+ * Grid layout: by-column is the default. Can be toggled by clicking
+ * on the [Layout] control button.
*
- * Prior to 3.7, it was always by-row, but by-column is more natural
- * for an alphabetized list.
+ * by-row vs by-column
+ * a b c a e i
+ * d e f b f j
+ * g h i c g -
+ * j - - d h -
*/
- bool by_column = true;
-
- QVBoxLayout *bl = new QVBoxLayout(grid);
- bl->addSpacing(fm.height());
- QGridLayout *gl = new QGridLayout();
- bl->addLayout(gl);
for (i = j = 0; extcmdlist[i].ef_txt; ++i) {
- if (interesting_command(i)) {
- QPushButton *pb = new QPushButton(extcmdlist[i].ef_txt, grid);
+ if (interesting_command(i, set)) {
+ QString btn_lbl = extcmdlist[i].ef_txt;
+ if (btn_lbl == "wait")
+ btn_lbl += " (rest)";
+ QPushButton *pb = new QPushButton(btn_lbl, grid);
pb->setMinimumSize(butw, pb->sizeHint().height());
// force the button to have fixed width or it can move around a
// pixel or two (tiny but visibly noticeable) when enableButtons()
// hides whole columns [see stretch comment below]
pb->setMaximumSize(pb->minimumSize());
- group->addButton(pb, i + 1);
+ // i+butoffset is value that will be passed to the click handler
+ group->addButton(pb, i + butoffset);
/*
- * by_column:
+ * by column: xcmd_by_row==false, the default
* 0..R-1 down first column, R..2*R-1 down second column, ...
- * otherwise:
+ * otherwise: by row
* 0..C-1 across first row, C..2*C-1 across second row, ...
*/
- int row = by_column ? j % nrows : j / ncols;
- int col = by_column ? j / nrows : j % ncols;
+ unsigned row = !byRow ? j % nrows : j / ncols;
+ unsigned col = !byRow ? j / nrows : j % ncols;
gl->addWidget(pb, row, col);
// these stretch settings prevent the grid from becoming very
// ugly when enableButtons() disables whole rows and/or columns
if (col == 0)
gl->setRowStretch(row, 1);
- buttons.append(pb);
+ // buttons[] vector is used by enableButtons()
+ buttons[j] = pb; // buttons.append(pb);
++j;
}
}
- group->addButton(can, 0);
- connect(group,SIGNAL(buttonPressed(int)),this,SLOT(done(int)));
+
+ connect(group, SIGNAL(buttonPressed(int)), this, SLOT(Button(int)));
bl->activate();
- l->activate();
+ xl->activate();
resize(1,1);
}
-void NetHackQtExtCmdRequestor::cancel()
+// Click handler for the ExtCmdRequestor widget
+int NetHackQtExtCmdRequestor::Button(int butnum)
+{
+ // 0..3 are control buttons, 4..N+3 are choice buttons.
+ // Widget return value is -1 for cancel (via reject),
+ // 0 for filter, layout, reset (via accept if circumstances warrant),
+ // 1..N for command choices (choice 0 is '#' and it isn't shown as
+ // a candidate since picking it is not useful).
+ switch (butnum) {
+ case 0:
+ Cancel();
+ /*NOTREACHED*/
+ break;
+ case 1:
+ Filter();
+ break;
+ case 2:
+ Layout();
+ break;
+ case 3:
+ Reset();
+ break;
+ default:
+ // 4..N-3 are the extended commands
+ done(butnum - butoffset + 1);
+ /*NOTREACHED*/
+ break;
+ }
+ return 0;
+}
+
+// Respond to a click on the [Cancel] button
+void NetHackQtExtCmdRequestor::Cancel()
{
reject();
+ /*NOTREACHED*/
+}
+
+// Respond to a click on the [Filter] button
+void NetHackQtExtCmdRequestor::Filter()
+{
+ // TEMP: step from one [sub]set to the next, then wrap back to the first.
+ if (++set > std::max(std::max(all_cmds, normal_cmds), wizard_cmds))
+ set = std::min(std::min(all_cmds, normal_cmds), wizard_cmds);
+
+ // TODO: put up a popup--dialog or maybe simple pick-one menu--that
+ // has player choose between all_cmds, normal_cmds, wizard_cmds.
+ // Only meaningful for wizard mode so maybe the temp version suffices.
+
+ if (set != qt_settings->xcmd_set) {
+ Retry();
+ /*NOTREACHED*/
+ }
+ return;
+}
+
+// Respond to a click on the [Layout] button
+void NetHackQtExtCmdRequestor::Layout()
+{
+ byRow = !byRow;
+ Retry();
+ /*NOTREACHED*/
+}
+
+// Respond to a click on the [Reset] button
+void NetHackQtExtCmdRequestor::Reset()
+{
+ // clear any typed text first (in case future changes are made to
+ // remember it across accept (retry); that would be intended for the
+ // [Layout] case rather than for [Reset])
+ bool clearprompt = (prompt->text() != "#");
+ if (clearprompt)
+ prompt->setText("#");
+
+ int teardown = 0;
+ if (set != (WizardMode ? all_cmds : normal_cmds))
+ set = all_cmds, ++teardown;
+ if (byRow)
+ byRow = false, ++teardown;
+ if (teardown) {
+ Retry();
+ /*NOTREACHED*/
+ }
+
+ if (clearprompt) { // was a subset, now need to show full set
+ DefaultActionIsCancel(true); // in case keyPressEvent cleared it
+ enableButtons(); // redraws the grid after discarding typed text above
+ }
+}
+
+// Return to ExtCmdRequestor::get()'s caller in order to be called back
+void NetHackQtExtCmdRequestor::Retry()
+{
+ // remember the current settings; they'll persist until changed again
+ qt_settings->updateXcmd(byRow, set);
+
+ // result 0 means that caller in core will call get_ext_cmd() again;
+ // current selection grid will be torn down, then new one created;
+ // TODO: have qt_get_ext_cmd() handle it instead of relying on core
+ setResult(0);
+ accept();
}
#define Ctrl(c) (0x1f & (c)) /* ASCII */
// Note: we don't necessarily have access to a terminal to query
// it for user's preferred kill character, so use hardcoded ^U.
+// Player who prefers something else can cope by using ESC instead.
#define KILL_CHAR Ctrl('u')
+// Receive the next character of typed input
void NetHackQtExtCmdRequestor::keyPressEvent(QKeyEvent *event)
{
+ /*
+ * This will select a command outright--as soon as enough chars
+ * to not be ambiguous are entered--but also narrows down visible
+ * choices [via enableButtons()] in the grid of clickable command
+ * buttons as the text-so-far makes many become impossible to match.
+ * Use of backspace/delete or ESC/kill restores suppressed choices
+ * to the grid as they become matchable again.
+ */
+
+ unsigned saveexactmatchindx = exactmatchindx;
+ // if previous KeyPressEvent cleared default, restore it now
+ DefaultActionIsCancel(true);
QString promptstr = prompt->text();
uchar uc = keyValue(event);
+
if (!uc) {
// shift or control or meta, another character should be coming
QWidget::keyPressEvent(event);
} else if (uc == '\033' || uc == KILL_CHAR) {
- // Escape when some response is already present kills that text
- // but keeps prompting; escape when response is empty cancels.
- // Kill gets rid of current text, if any, and always re-prompts.
+ // <escape> when partial response is present kills that text
+ // but keeps prompting; <escape> when response is empty cancels.
+ // Kill gets rid of pending text, if any, and always re-prompts.
if (uc == '\033' && promptstr == "#")
reject(); // cancel() if ESC used when string is empty
- prompt->setText("#");
+ prompt->setText("#"); // reset to empty ('#' is always present)
enableButtons();
} else if (uc == '\b' || uc == '\177') {
if (promptstr != "#")
|| uc > std::max('z', 'Z')) {
reject(); // done()
} else {
- // <return> is necessary if one command is a leading substring
- // of another and superfluous otherwise
- boolean checkexact = (uc == '\n' || uc == '\r' || uc == ' ');
- if (!checkexact)
- promptstr += QChar(uc); // event()->text()
+ /*
+ * <return> or <space> is necessary if one command is a
+ * leading substring of another and superfluous otherwise.
+ * (When a command is not a prefix of another, it will have
+ * been selected before reaching its last letter.)
+ *
+ * If we got an exact match with the last key, we're expecting
+ * a <return> or <space> to explicitly choose it now but might
+ * get next letter of the longer command (or get a backspace).
+ *
+ * If we get an exact match this time, then stop showing
+ * [Cancel] as the default action for <return>.
+ * (That's a visual cue for the player, not a requirement to
+ * prevent <return> from triggering the default action.)
+ * If it's not the default action upon the next key press,
+ * we'll change that back (done above).
+ *
+ * TODO?
+ * Implement <tab> support: if promptstr matches multiple
+ * commands but they all have the next one or more letters in
+ * common, allow <tab> to add the common letters to promptstr.
+ */
+ bool checkexact = (uc == '\n' || uc == '\r' || uc == ' ');
+ if (!checkexact) {
+ // force lower case instead of rejecting upper case
+ if (isupper(uc))
+ uc = tolower(uc);
+ promptstr += QChar(uc); // add new char to typed text
+ }
QString typedstr = promptstr.mid(1); // skip the '#'
unsigned matches = 0;
unsigned matchindx = 0;
- for (unsigned i=0; extcmdlist[i].ef_txt; i++) {
- if (!interesting_command(i))
+ for (unsigned i = 0; extcmdlist[i].ef_txt; ++i) {
+ if (!interesting_command(i, set))
continue;
- QString cmdtxt = QString(extcmdlist[i].ef_txt);
+ const QString &cmdtxt = QString(extcmdlist[i].ef_txt);
if (cmdtxt.startsWith(typedstr)) {
+ bool is_exact = (cmdtxt == typedstr);
if (checkexact) {
- if (cmdtxt == typedstr) {
+ if (is_exact) {
matchindx = i;
matches = 1;
break;
}
} else {
+ if (is_exact)
+ DefaultActionIsCancel(false, i); // clear default
if (++matches >= 2)
break;
matchindx = i;
}
}
}
- if (matches == 1)
+ if (matches == 1) {
done(matchindx + 1);
- else if (checkexact)
+ } else if (checkexact) {
+ // <return> or <space> without a pending exact match; cancel
reject();
- else if (matches >= 2)
+ } else if (matches >= 2) {
+ // update the text-so-far
prompt->setText(promptstr);
+ } else if (saveexactmatchindx != xcmdNoMatch) {
+ // had a pending exact match but typed something other than
+ // <return> which didn't yield another match; prompt string
+ // hasn't been updated so still have a pending exact match
+ DefaultActionIsCancel(false, saveexactmatchindx);
+ }
enableButtons();
}
}
+// Actual widget execution, used after calling NetHackQtExtCmdRequestor().
int NetHackQtExtCmdRequestor::get()
{
- const int none = -10;
resize(1,1); // pack
centerOnMain(this);
// Add any keys presently buffered to the prompt
- setResult(none);
- while (NetHackQtBind::qt_kbhit() && result() == none) {
+ setResult(xcmdNone);
+ while (NetHackQtBind::qt_kbhit() && result() == xcmdNone) {
int ch = NetHackQtBind::qt_nhgetch();
QKeyEvent event(QEvent::KeyPress, 0, Qt::NoModifier, QChar(ch));
keyPressEvent(&event);
}
- if (result() == none)
+ if (result() == xcmdNone)
exec();
- return result()-1;
+ return result() - 1;
}
// Enable only buttons that match the current prompt string