Auto feature for minibuffer toolbar

Now the minibuffer toolbar is "auto" by default. It is opened by
command-execute (M-x) and closed when the command is executed without error.

* make lyx::dispatch return a DispatchResult struct

* there is a new MINIBUFFER type of toolbar, that can be used for this use.

* remove special handling of M-x in minnibuffer; Escape can be used instead. Fix focus in this case.

* when minibuffer toolbar is "auto", make the toolbar close itself after
  - a command has been executed without error
  - an empty command has been executed
  - the Escape key has been used
This commit is contained in:
Jean-Marc Lasgouttes 2015-04-18 19:10:33 +02:00
parent 8a27143e72
commit fdcff02a31
15 changed files with 63 additions and 63 deletions

View File

@ -56,5 +56,5 @@ Toolbars
"math" "auto,math,bottom" "math" "auto,math,bottom"
"mathmacrotemplate" "auto,mathmacrotemplate,bottom" "mathmacrotemplate" "auto,mathmacrotemplate,bottom"
"ipa" "auto,ipa,bottom" "ipa" "auto,ipa,bottom"
"minibuffer" "off,bottom" "minibuffer" "auto,minibuffer,bottom"
End End

View File

@ -1386,7 +1386,7 @@ FuncStatus getStatus(FuncRequest const & action)
} }
void dispatch(FuncRequest const & action) DispatchResult const & dispatch(FuncRequest const & action)
{ {
LAPPERR(theApp()); LAPPERR(theApp());
return theApp()->dispatch(action); return theApp()->dispatch(action);
@ -1396,7 +1396,7 @@ void dispatch(FuncRequest const & action)
void dispatch(FuncRequest const & action, DispatchResult & dr) void dispatch(FuncRequest const & action, DispatchResult & dr)
{ {
LAPPERR(theApp()); LAPPERR(theApp());
return theApp()->dispatch(action, dr); theApp()->dispatch(action, dr);
} }

View File

@ -135,7 +135,7 @@ private:
bool first_start; bool first_start;
friend FuncStatus getStatus(FuncRequest const & action); friend FuncStatus getStatus(FuncRequest const & action);
friend void dispatch(FuncRequest const & action); friend DispatchResult const & dispatch(FuncRequest const & action);
friend void dispatch(FuncRequest const & action, DispatchResult & dr); friend void dispatch(FuncRequest const & action, DispatchResult & dr);
friend std::vector<std::string> & theFilesToLoad(); friend std::vector<std::string> & theFilesToLoad();
friend BufferList & theBufferList(); friend BufferList & theBufferList();
@ -175,7 +175,7 @@ void execBatchCommands();
FuncStatus getStatus(FuncRequest const & action); FuncStatus getStatus(FuncRequest const & action);
/// ///
void dispatch(FuncRequest const & action); DispatchResult const & dispatch(FuncRequest const & action);
/// ///
void dispatch(FuncRequest const & action, DispatchResult & dr); void dispatch(FuncRequest const & action, DispatchResult & dr);

View File

@ -177,7 +177,7 @@ public:
/// Every user command is processed here, either invocated from /// Every user command is processed here, either invocated from
/// keyboard or from the GUI. All GUI objects, including buttons and /// keyboard or from the GUI. All GUI objects, including buttons and
/// menus should use this class and never call kernel functions directly. /// menus should use this class and never call kernel functions directly.
virtual void dispatch(FuncRequest const &) = 0; virtual DispatchResult const & dispatch(FuncRequest const &) = 0;
/// LyX dispatcher: executes lyx actions and returns result. /// LyX dispatcher: executes lyx actions and returns result.
virtual void dispatch(FuncRequest const &, DispatchResult & dr) = 0; virtual void dispatch(FuncRequest const &, DispatchResult & dr) = 0;

View File

@ -965,6 +965,9 @@ struct GuiApplication::Private
/// ///
KeyModifier meta_fake_bit; KeyModifier meta_fake_bit;
/// The result of last dispatch action
DispatchResult dispatch_result_;
/// Multiple views container. /// Multiple views container.
/** /**
* Warning: This must not be a smart pointer as the destruction of the * Warning: This must not be a smart pointer as the destruction of the
@ -1372,7 +1375,7 @@ static docstring makeDispatchMessage(docstring const & msg,
} }
void GuiApplication::dispatch(FuncRequest const & cmd) DispatchResult const & GuiApplication::dispatch(FuncRequest const & cmd)
{ {
Buffer * buffer = 0; Buffer * buffer = 0;
if (current_view_ && current_view_->currentBufferView()) { if (current_view_ && current_view_->currentBufferView()) {
@ -1392,6 +1395,9 @@ void GuiApplication::dispatch(FuncRequest const & cmd)
// the buffer may have been closed by one action // the buffer may have been closed by one action
if (theBufferList().isLoaded(buffer)) if (theBufferList().isLoaded(buffer))
buffer->undo().endUndoGroup(); buffer->undo().endUndoGroup();
d->dispatch_result_ = dr;
return d->dispatch_result_;
} }

View File

@ -62,7 +62,7 @@ public:
/// \name Methods inherited from Application class /// \name Methods inherited from Application class
//@{ //@{
void dispatch(FuncRequest const &); DispatchResult const & dispatch(FuncRequest const &);
void dispatch(FuncRequest const &, DispatchResult & dr); void dispatch(FuncRequest const &, DispatchResult & dr);
FuncStatus getStatus(FuncRequest const & cmd) const; FuncStatus getStatus(FuncRequest const & cmd) const;
void restoreGuiSession(); void restoreGuiSession();

View File

@ -108,12 +108,11 @@ GuiCommandBuffer::GuiCommandBuffer(GuiView * view)
edit_->setMinimumSize(edit_->sizeHint()); edit_->setMinimumSize(edit_->sizeHint());
edit_->setFocusPolicy(Qt::ClickFocus); edit_->setFocusPolicy(Qt::ClickFocus);
connect(edit_, SIGNAL(escapePressed()), this, SLOT(cancel()));
connect(edit_, SIGNAL(returnPressed()), this, SLOT(dispatch())); connect(edit_, SIGNAL(returnPressed()), this, SLOT(dispatch()));
connect(edit_, SIGNAL(tabPressed()), this, SLOT(complete())); connect(edit_, SIGNAL(tabPressed()), this, SLOT(complete()));
connect(edit_, SIGNAL(upPressed()), this, SLOT(up())); connect(edit_, SIGNAL(upPressed()), this, SLOT(up()));
connect(edit_, SIGNAL(downPressed()), this, SLOT(down())); connect(edit_, SIGNAL(downPressed()), this, SLOT(down()));
connect(edit_, SIGNAL(hidePressed()), this, SLOT(hideParent())); connect(edit_, SIGNAL(escapePressed()), this, SLOT(hideParent()));
layout->addWidget(upPB, 0); layout->addWidget(upPB, 0);
layout->addWidget(downPB, 0); layout->addWidget(downPB, 0);
@ -138,22 +137,19 @@ GuiCommandBuffer::GuiCommandBuffer(GuiView * view)
} }
void GuiCommandBuffer::cancel()
{
view_->setFocus();
edit_->setText(QString());
}
void GuiCommandBuffer::dispatch() void GuiCommandBuffer::dispatch()
{ {
QString const cmd = edit_->text(); std::string const cmd = fromqstr(edit_->text());
view_->setFocus(); if (!cmd.empty())
edit_->setText(QString()); theSession().lastCommands().add(cmd);
edit_->clearFocus(); DispatchResult const & dr = dispatch(cmd);
std::string const cmd_ = fromqstr(cmd); if (!dr.error()) {
theSession().lastCommands().add(cmd_); view_->setFocus();
dispatch(cmd_); edit_->setText(QString());
edit_->clearFocus();
// If the toolbar was "auto", it is not needed anymore
view_->resetCommandExecute();
}
} }
@ -257,9 +253,9 @@ void GuiCommandBuffer::down()
void GuiCommandBuffer::hideParent() void GuiCommandBuffer::hideParent()
{ {
view_->setFocus(); view_->setFocus();
view_->resetCommandExecute();
edit_->setText(QString()); edit_->setText(QString());
edit_->clearFocus(); edit_->clearFocus();
hide();
} }
@ -301,13 +297,6 @@ docstring const GuiCommandBuffer::getCurrentState() const
} }
void GuiCommandBuffer::hide() const
{
FuncRequest cmd(LFUN_COMMAND_EXECUTE, "off");
lyx::dispatch(cmd);
}
vector<string> const vector<string> const
GuiCommandBuffer::completions(string const & prefix, string & new_prefix) GuiCommandBuffer::completions(string const & prefix, string & new_prefix)
{ {
@ -347,10 +336,12 @@ GuiCommandBuffer::completions(string const & prefix, string & new_prefix)
} }
void GuiCommandBuffer::dispatch(string const & str) DispatchResult const & GuiCommandBuffer::dispatch(string const & str)
{ {
if (str.empty()) if (str.empty()) {
return; static DispatchResult empty_dr;
return empty_dr;
}
history_.push_back(trim(str)); history_.push_back(trim(str));
history_pos_ = history_.end(); history_pos_ = history_.end();
@ -358,7 +349,7 @@ void GuiCommandBuffer::dispatch(string const & str)
downPB->setEnabled(history_pos_ != history_.end()); downPB->setEnabled(history_pos_ != history_.end());
FuncRequest func = lyxaction.lookupFunc(str); FuncRequest func = lyxaction.lookupFunc(str);
func.setOrigin(FuncRequest::COMMANDBUFFER); func.setOrigin(FuncRequest::COMMANDBUFFER);
lyx::dispatch(func); return lyx::dispatch(func);
} }
} // namespace frontend } // namespace frontend

View File

@ -24,6 +24,9 @@
class QListWidgetItem; class QListWidgetItem;
namespace lyx { namespace lyx {
class DispatchResult;
namespace frontend { namespace frontend {
class GuiView; class GuiView;
@ -37,8 +40,6 @@ public:
GuiCommandBuffer(GuiView * view); GuiCommandBuffer(GuiView * view);
public Q_SLOTS: public Q_SLOTS:
/// cancel command compose
void cancel();
/// dispatch a command /// dispatch a command
void dispatch(); void dispatch();
/// tab-complete /// tab-complete
@ -67,9 +68,6 @@ private:
/// return the font and depth in the active BufferView as a message. /// return the font and depth in the active BufferView as a message.
docstring const getCurrentState() const; docstring const getCurrentState() const;
/// hide the command buffer.
void hide() const;
/// open a listbox and show the contents of the list. When reversed /// open a listbox and show the contents of the list. When reversed
/// is true, the contents of the list is filled bottom-up. /// is true, the contents of the list is filled bottom-up.
void showList(std::vector<std::string> const & list, void showList(std::vector<std::string> const & list,
@ -80,7 +78,7 @@ private:
std::string & new_prefix); std::string & new_prefix);
/// dispatch a command /// dispatch a command
void dispatch(std::string const & str); DispatchResult const & dispatch(std::string const & str);
/// available command names /// available command names
std::vector<std::string> commands_; std::vector<std::string> commands_;

View File

@ -45,14 +45,6 @@ void GuiCommandEdit::keyPressEvent(QKeyEvent * e)
downPressed(); downPressed();
break; break;
case Qt::Key_X:
if (e->modifiers() == Qt::AltModifier
|| e->modifiers() == Qt::MetaModifier) {
// emit signal
hidePressed();
break;
}
default: default:
QLineEdit::keyPressEvent(e); QLineEdit::keyPressEvent(e);
break; break;

View File

@ -35,8 +35,6 @@ Q_SIGNALS:
void downPressed(); void downPressed();
/// complete /// complete
void tabPressed(); void tabPressed();
/// leave and hide command buffer
void hidePressed();
protected: protected:
/// ///

View File

@ -323,8 +323,12 @@ void GuiToolbar::add(ToolbarItem const & item)
void GuiToolbar::update(int context) void GuiToolbar::update(int context)
{ {
if (visibility_ & Toolbars::AUTO) if (visibility_ & Toolbars::AUTO) {
bool const was_visible = isVisible();
setVisible(visibility_ & context & Toolbars::ALLOWAUTO); setVisible(visibility_ & context & Toolbars::ALLOWAUTO);
if (isVisible() && !was_visible && commandBuffer())
commandBuffer()->setFocus();
}
// update visible toolbars only // update visible toolbars only
if (!isVisible()) if (!isVisible())

View File

@ -508,7 +508,8 @@ QSet<Buffer const *> GuiView::GuiViewPrivate::busyBuffers;
GuiView::GuiView(int id) GuiView::GuiView(int id)
: d(*new GuiViewPrivate(this)), id_(id), closing_(false), busy_(0) : d(*new GuiViewPrivate(this)), id_(id), closing_(false), busy_(0),
command_execute_(false)
{ {
// GuiToolbars *must* be initialised before the menu bar. // GuiToolbars *must* be initialised before the menu bar.
normalSizedIcons(); // at least on Mac the default is 32 otherwise, which is huge normalSizedIcons(); // at least on Mac the default is 32 otherwise, which is huge
@ -1343,6 +1344,13 @@ void GuiView::setBusy(bool busy)
} }
void GuiView::resetCommandExecute()
{
command_execute_ = false;
updateToolbars();
}
double GuiView::pixelRatio() const double GuiView::pixelRatio() const
{ {
#if QT_VERSION >= 0x050000 #if QT_VERSION >= 0x050000
@ -1547,6 +1555,8 @@ void GuiView::updateToolbars()
context |= Toolbars::MATHMACROTEMPLATE; context |= Toolbars::MATHMACROTEMPLATE;
if (lyx::getStatus(FuncRequest(LFUN_IN_IPA)).enabled()) if (lyx::getStatus(FuncRequest(LFUN_IN_IPA)).enabled())
context |= Toolbars::IPA; context |= Toolbars::IPA;
if (command_execute_)
context |= Toolbars::MINIBUFFER;
for (ToolbarMap::iterator it = d.toolbars_.begin(); it != end; ++it) for (ToolbarMap::iterator it = d.toolbars_.begin(); it != end; ++it)
it->second->update(context); it->second->update(context);
@ -3624,14 +3634,7 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
break; break;
case LFUN_COMMAND_EXECUTE: { case LFUN_COMMAND_EXECUTE: {
bool const show_it = cmd.argument() != "off"; command_execute_ = true;
// FIXME: this is a hack, "minibuffer" should not be
// hardcoded.
if (GuiToolbar * t = toolbar("minibuffer")) {
t->setVisible(show_it);
if (show_it && t->commandBuffer())
t->commandBuffer()->setFocus();
}
break; break;
} }
case LFUN_DROP_LAYOUTS_CHOICE: case LFUN_DROP_LAYOUTS_CHOICE:

View File

@ -84,6 +84,8 @@ public:
/// are we busy ? /// are we busy ?
bool busy() const; bool busy() const;
/// Signal that the any "auto" minibuffer can be closed now.
void resetCommandExecute();
/// \name Generic accessor functions /// \name Generic accessor functions
//@{ //@{
@ -450,6 +452,9 @@ private:
/// functions that call setBusy; /// functions that call setBusy;
int busy_; int busy_;
/// Request to open the command toolbar if it is "auto"
bool command_execute_;
}; };
} // namespace frontend } // namespace frontend

View File

@ -348,6 +348,8 @@ void Toolbars::readToolbarSettings(Lexer & lex)
flag = MATHMACROTEMPLATE; flag = MATHMACROTEMPLATE;
else if (!compare_ascii_no_case(*cit, "review")) else if (!compare_ascii_no_case(*cit, "review"))
flag = REVIEW; flag = REVIEW;
else if (!compare_ascii_no_case(*cit, "minibuffer"))
flag = MINIBUFFER;
else if (!compare_ascii_no_case(*cit, "top")) else if (!compare_ascii_no_case(*cit, "top"))
flag = TOP; flag = TOP;
else if (!compare_ascii_no_case(*cit, "bottom")) else if (!compare_ascii_no_case(*cit, "bottom"))

View File

@ -110,7 +110,8 @@ public:
MATHMACROTEMPLATE = 1024, //< show in math macro template MATHMACROTEMPLATE = 1024, //< show in math macro template
SAMEROW = 2048, //place to the current row, no new line SAMEROW = 2048, //place to the current row, no new line
IPA = 4096, //< show when in IPA inset IPA = 4096, //< show when in IPA inset
ALLOWAUTO = MATH | TABLE | REVIEW | MATHMACROTEMPLATE | IPA MINIBUFFER = 8192, //< show when command-execute has been invoked
ALLOWAUTO = MATH | TABLE | REVIEW | MATHMACROTEMPLATE | IPA | MINIBUFFER
}; };
typedef std::vector<ToolbarInfo> Infos; typedef std::vector<ToolbarInfo> Infos;