X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt4%2FGuiCommandBuffer.cpp;h=b66860439b69ad3681032c9ad48519da7c663063;hb=425d092204118ea6c24c28e85fdf03fcf2bb51a4;hp=2817ab553556c6347f11821a458bf8d141d5b1b4;hpb=a1cec91afaca91968b46e695533c10ad2a3f73d3;p=lyx.git diff --git a/src/frontends/qt4/GuiCommandBuffer.cpp b/src/frontends/qt4/GuiCommandBuffer.cpp index 2817ab5535..b66860439b 100644 --- a/src/frontends/qt4/GuiCommandBuffer.cpp +++ b/src/frontends/qt4/GuiCommandBuffer.cpp @@ -3,6 +3,8 @@ * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * + * \author Lars + * \author Asger and Jürgen * \author John Levon * * Full author contact details are available in file CREDITS. @@ -10,19 +12,25 @@ #include -// Qt defines a macro 'signals' that clashes with a boost namespace. -// All is well if the namespace is visible first. -#include "GuiView.h" - #include "GuiCommandBuffer.h" + +#include "GuiApplication.h" #include "GuiCommandEdit.h" +#include "GuiView.h" #include "qt_helpers.h" -#include "support/filetools.h" +#include "BufferView.h" +#include "Cursor.h" +#include "LyXFunc.h" +#include "LyXAction.h" +#include "FuncRequest.h" +#include "Session.h" + +#include "support/lyxalgo.h" +#include "support/lstrings.h" #include #include -#include #include #include #include @@ -30,10 +38,8 @@ #include #include -using lyx::support::libFileSearch; - -using std::vector; -using std::string; +using namespace std; +using namespace lyx::support; namespace lyx { namespace frontend { @@ -50,14 +56,15 @@ public: setAttribute(Qt::WA_DeleteOnClose); } protected: - void mouseReleaseEvent(QMouseEvent * ev) { - if (ev->x() < 0 || ev->y() < 0 - || ev->x() > width() || ev->y() > height()) { - hide(); - } else { - // emit signal - itemPressed(currentItem()); + bool event(QEvent * ev) { + if (ev->type() == QEvent::MouseButtonPress) { + QMouseEvent * me = static_cast(ev); + if (me->x() < 0 || me->y() < 0 + || me->x() > width() || me->y() > height()) + hide(); + return true; } + return QListWidget::event(ev); } void keyPressEvent(QKeyEvent * ev) { @@ -66,7 +73,7 @@ protected: return; } else if (ev->key() == Qt::Key_Return || ev->key() == Qt::Key_Space) { // emit signal - itemPressed(currentItem()); + itemClicked(currentItem()); } else QListWidget::keyPressEvent(ev); } @@ -75,23 +82,27 @@ protected: } // end of anon -GuiCommandBuffer::GuiCommandBuffer(GuiViewBase * view) - : view_(view), controller_(*view) +GuiCommandBuffer::GuiCommandBuffer(GuiView * view) + : view_(view) { - QPixmap qpup(toqstr(libFileSearch("images", "up", "png").absFilename())); - QPixmap qpdown(toqstr(libFileSearch("images", "down", "png").absFilename())); + transform(lyxaction.func_begin(), lyxaction.func_end(), + back_inserter(commands_), firster()); + + QPixmap qpup = getPixmap("images/", "up", "png"); + QPixmap qpdown = getPixmap("images/", "down", "png"); QVBoxLayout * top = new QVBoxLayout(this); QHBoxLayout * layout = new QHBoxLayout(0); - QPushButton * up = new QPushButton(qpup, "", this); - up->setMaximumSize(24, 24); - up->setToolTip(qt_("Previous command")); - connect(up, SIGNAL(clicked()), this, SLOT(up())); - QPushButton * down = new QPushButton(qpdown, "", this); - down->setToolTip(qt_("Next command")); - down->setMaximumSize(24, 24); - connect(down, SIGNAL(clicked()), this, SLOT(down())); + upPB = new QPushButton(qpup, "", this); + upPB->setToolTip(qt_("List of previous commands")); + upPB->setMaximumSize(24, 24); + downPB = new QPushButton(qpdown, "", this); + downPB->setToolTip(qt_("Next command")); + downPB->setMaximumSize(24, 24); + downPB->setEnabled(false); + connect(downPB, SIGNAL(clicked()), this, SLOT(down())); + connect(upPB, SIGNAL(pressed()), this, SLOT(listHistoryUp())); edit_ = new GuiCommandEdit(this); edit_->setMinimumSize(edit_->sizeHint()); @@ -104,13 +115,26 @@ GuiCommandBuffer::GuiCommandBuffer(GuiViewBase * view) connect(edit_, SIGNAL(downPressed()), this, SLOT(down())); connect(edit_, SIGNAL(hidePressed()), this, SLOT(hideParent())); - layout->addWidget(up, 0); - layout->addWidget(down, 0); + layout->addWidget(upPB, 0); + layout->addWidget(downPB, 0); layout->addWidget(edit_, 10); layout->setMargin(0); top->addLayout(layout); top->setMargin(0); setFocusProxy(edit_); + + LastCommandsSection::LastCommands last_commands + = theSession().lastCommands().getcommands(); + LastCommandsSection::LastCommands::const_iterator it + = last_commands.begin(); + LastCommandsSection::LastCommands::const_iterator end + = last_commands.end(); + + upPB->setEnabled(it != end); + + for(; it != end; ++it) + history_.push_back(*it); + history_pos_ = history_.end(); } @@ -123,10 +147,25 @@ void GuiCommandBuffer::cancel() void GuiCommandBuffer::dispatch() { - controller_.dispatch(fromqstr(edit_->text())); + QString cmd = edit_->text(); view_->setFocus(); edit_->setText(QString()); edit_->clearFocus(); + std::string const cmd_ = fromqstr(cmd); + theSession().lastCommands().add(cmd_); + dispatch(cmd_); +} + + +void GuiCommandBuffer::listHistoryUp() +{ + if (history_.size()==1) { + edit_->setText(toqstr(history_.back())); + upPB->setEnabled(false); + return; + } + QPoint const & pos = upPB->mapToGlobal(QPoint(0, 0)); + showList(history_, pos, true); } @@ -134,52 +173,55 @@ void GuiCommandBuffer::complete() { string const input = fromqstr(edit_->text()); string new_input; - vector comp = controller_.completions(input, new_input); - - if (comp.empty() && new_input == input) { - // show_info_suffix(qt_("[no match]"), input); - return; - } + vector const & comp = completions(input, new_input); if (comp.empty()) { - edit_->setText(toqstr(new_input)); - // show_info_suffix(("[only completion]"), new_input + ' '); + if (new_input != input) + edit_->setText(toqstr(new_input)); return; } edit_->setText(toqstr(new_input)); + QPoint const & pos = edit_->mapToGlobal(QPoint(0, 0)); + showList(comp, pos); +} - QTempListBox * list = new QTempListBox; +void GuiCommandBuffer::showList(vector const & list, + QPoint const & pos, bool reversed) const +{ + QTempListBox * listBox = new QTempListBox; // For some reason the scrollview's contents are larger // than the number of actual items... - vector::const_iterator cit = comp.begin(); - vector::const_iterator end = comp.end(); - for (; cit != end; ++cit) - list->addItem(toqstr(*cit)); - - list->resize(list->sizeHint()); - QPoint const pos = edit_->mapToGlobal(QPoint(0, 0)); + vector::const_iterator cit = list.begin(); + vector::const_iterator end = list.end(); + for (; cit != end; ++cit) { + if (reversed) + listBox->insertItem(0, toqstr(*cit)); + else + listBox->addItem(toqstr(*cit)); + } - int const y = std::max(0, pos.y() - list->height()); + listBox->resize(listBox->sizeHint()); - list->move(pos.x(), y); + int const y = max(0, pos.y() - listBox->height()); + listBox->move(pos.x(), y); - connect(list, SIGNAL(itemPressed(QListWidgetItem *)), - this, SLOT(complete_selected(QListWidgetItem *))); - connect(list, SIGNAL(itemActivated(QListWidgetItem *)), - this, SLOT(complete_selected(QListWidgetItem *))); + connect(listBox, SIGNAL(itemClicked(QListWidgetItem *)), + this, SLOT(itemSelected(QListWidgetItem *))); + connect(listBox, SIGNAL(itemActivated(QListWidgetItem *)), + this, SLOT(itemSelected(QListWidgetItem *))); - list->show(); - list->setFocus(); + listBox->show(); + listBox->setFocus(); } -void GuiCommandBuffer::complete_selected(QListWidgetItem * item) +void GuiCommandBuffer::itemSelected(QListWidgetItem * item) { QWidget const * widget = static_cast(sender()); const_cast(widget)->hide(); - edit_->setText(item->text() + ' '); + edit_->setText(item->text()+ ' '); edit_->activateWindow(); edit_->setFocus(); } @@ -188,57 +230,138 @@ void GuiCommandBuffer::complete_selected(QListWidgetItem * item) void GuiCommandBuffer::up() { string const input = fromqstr(edit_->text()); - string const h = controller_.historyUp(); + string const h = historyUp(); - if (h.empty()) { - // show_info_suffix(qt_("[Beginning of history]"), input); - } else { + if (!h.empty()) edit_->setText(toqstr(h)); - } + + upPB->setEnabled(history_pos_ != history_.begin()); + downPB->setEnabled(history_pos_ != history_.end()); } void GuiCommandBuffer::down() { string const input = fromqstr(edit_->text()); - string const h = controller_.historyDown(); + string const h = historyDown(); - if (h.empty()) { - // show_info_suffix(qt_("[End of history]"), input); - } else { + if (!h.empty()) edit_->setText(toqstr(h)); - } -} + downPB->setEnabled(!history_.empty() + && history_pos_ != history_.end() - 1); + upPB->setEnabled(history_pos_ != history_.begin()); +} + void GuiCommandBuffer::hideParent() { view_->setFocus(); edit_->setText(QString()); edit_->clearFocus(); - controller_.hide(); + hide(); +} + + +namespace { + +class prefix_p { +public: + string p; + prefix_p(string const & s) : p(s) {} + bool operator()(string const & s) const { return prefixIs(s, p); } +}; + +} // end of anon namespace + + +string const GuiCommandBuffer::historyUp() +{ + if (history_pos_ == history_.begin()) + return string(); + + return *(--history_pos_); } -#if 0 -void XMiniBuffer::show_info_suffix(string const & suffix, string const & input) +string const GuiCommandBuffer::historyDown() { - stored_input_ = input; - info_suffix_shown_ = true; - set_input(input + ' ' + suffix); - suffix_timer_->start(); + if (history_pos_ == history_.end()) + return string(); + if (history_pos_ + 1 == history_.end()) + return string(); + + return *(++history_pos_); +} + + +docstring const GuiCommandBuffer::getCurrentState() const +{ + return view_->currentBufferView()->cursor().currentState(); } -void XMiniBuffer::suffix_timeout() +void GuiCommandBuffer::hide() const { - info_suffix_shown_ = false; - set_input(stored_input_); + FuncRequest cmd(LFUN_COMMAND_EXECUTE, "off"); + lyx::dispatch(cmd); } -#endif + +vector const +GuiCommandBuffer::completions(string const & prefix, string & new_prefix) +{ + vector comp; + + copy_if(commands_.begin(), commands_.end(), + back_inserter(comp), prefix_p(prefix)); + + if (comp.empty()) { + new_prefix = prefix; + return comp; + } + + if (comp.size() == 1) { + new_prefix = comp[0]; + return vector(); + } + + // find maximal available prefix + string const tmp = comp[0]; + string test = prefix; + if (tmp.length() > test.length()) + test += tmp[test.length()]; + while (test.length() < tmp.length()) { + vector vtmp; + copy_if(comp.begin(), comp.end(), + back_inserter(vtmp), prefix_p(test)); + if (vtmp.size() != comp.size()) { + test.erase(test.length() - 1); + break; + } + test += tmp[test.length()]; + } + + new_prefix = test; + return comp; +} + + +void GuiCommandBuffer::dispatch(string const & str) +{ + if (str.empty()) + return; + + history_.push_back(trim(str)); + history_pos_ = history_.end(); + upPB->setEnabled(history_pos_ != history_.begin()); + downPB->setEnabled(history_pos_ != history_.end()); + FuncRequest func = lyxaction.lookupFunc(str); + func.origin = FuncRequest::COMMANDBUFFER; + lyx::dispatch(func); +} } // namespace frontend } // namespace lyx -#include "GuiCommandBuffer_moc.cpp" +#include "moc_GuiCommandBuffer.cpp"