mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 13:18:28 +00:00
UI Command Buffer improvements.
* the history is stored in the session file and restored in the next LyX session, * the lists now disappear when the mouse is released in stead of pressed, * correct enabling/disabling of the up/down button, * hide the lists when clicked outside the list. Now using the function event() and check for a mouseButtonPressEvent instead of using mouseReleaseEvent(). The latter is only called when the mouse button is released inside the widget, but we want to use this event to detect a mouseclick outside the list. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@28250 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
53064b49e8
commit
cf40884454
@ -33,6 +33,7 @@ string const sec_lastopened = "[last opened files]";
|
||||
string const sec_bookmarks = "[bookmarks]";
|
||||
string const sec_session = "[session info]";
|
||||
string const sec_toolbars = "[toolbars]";
|
||||
string const sec_lastcommands = "[last commands]";
|
||||
|
||||
} // anon namespace
|
||||
|
||||
@ -301,8 +302,64 @@ BookmarksSection::Bookmark const & BookmarksSection::bookmark(unsigned int i) co
|
||||
}
|
||||
|
||||
|
||||
Session::Session(unsigned int num) :
|
||||
last_files(num)
|
||||
LastCommandsSection::LastCommandsSection(unsigned int num) :
|
||||
default_num_last_commands(30),
|
||||
absolute_max_last_commands(100)
|
||||
{
|
||||
setNumberOfLastCommands(num);
|
||||
}
|
||||
|
||||
|
||||
void LastCommandsSection::read(istream & is)
|
||||
{
|
||||
string tmp;
|
||||
do {
|
||||
char c = is.peek();
|
||||
if (c == '[')
|
||||
break;
|
||||
getline(is, tmp);
|
||||
if (tmp == "" || tmp[0] == '#' || tmp[0] == ' ')
|
||||
continue;
|
||||
|
||||
lastcommands.push_back(tmp);
|
||||
} while (is.good());
|
||||
}
|
||||
|
||||
|
||||
void LastCommandsSection::write(ostream & os) const
|
||||
{
|
||||
os << '\n' << sec_lastcommands << '\n';
|
||||
copy(lastcommands.begin(), lastcommands.end(),
|
||||
ostream_iterator<std::string>(os, "\n"));
|
||||
}
|
||||
|
||||
|
||||
void LastCommandsSection::setNumberOfLastCommands(unsigned int no)
|
||||
{
|
||||
if (0 < no && no <= absolute_max_last_commands)
|
||||
num_lastcommands = no;
|
||||
else {
|
||||
LYXERR(Debug::INIT, "LyX: session: too many last commands\n"
|
||||
<< "\tdefault (=" << default_num_last_commands << ") used.");
|
||||
num_lastcommands = default_num_last_commands;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LastCommandsSection::add(std::string const & string)
|
||||
{
|
||||
lastcommands.push_back(string);
|
||||
}
|
||||
|
||||
|
||||
void LastCommandsSection::clear()
|
||||
{
|
||||
lastcommands.clear();
|
||||
}
|
||||
|
||||
|
||||
Session::Session(unsigned int num_last_files, unsigned int num_last_commands) :
|
||||
last_files(num_last_files), last_commands(num_last_commands)
|
||||
{
|
||||
// locate the session file
|
||||
// note that the session file name 'session' is hard-coded
|
||||
@ -333,6 +390,9 @@ void Session::readFile()
|
||||
lastFilePos().read(is);
|
||||
else if (tmp == sec_bookmarks)
|
||||
bookmarks().read(is);
|
||||
else if (tmp == sec_lastcommands)
|
||||
lastCommands().read(is);
|
||||
|
||||
else
|
||||
LYXERR(Debug::INIT, "LyX: Warning: unknown Session section: " << tmp);
|
||||
}
|
||||
@ -349,6 +409,7 @@ void Session::writeFile() const
|
||||
lastFiles().write(os);
|
||||
lastOpened().write(os);
|
||||
lastFilePos().write(os);
|
||||
lastCommands().write(os);
|
||||
bookmarks().write(os);
|
||||
} else
|
||||
LYXERR(Debug::INIT, "LyX: Warning: unable to save Session: "
|
||||
|
@ -27,6 +27,7 @@
|
||||
3. opened files when a lyx session is closed (lastopened)
|
||||
4. bookmarks
|
||||
5. general purpose session info in the form of key/value pairs
|
||||
6. the latest commands entered in the command buffer (lastcommands)
|
||||
*/
|
||||
namespace lyx {
|
||||
|
||||
@ -263,11 +264,59 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class LastCommandsSection : SessionSection
|
||||
{
|
||||
public:
|
||||
///
|
||||
typedef std::vector<std::string> LastCommands;
|
||||
|
||||
public:
|
||||
///
|
||||
LastCommandsSection(unsigned int num);
|
||||
///
|
||||
void read(std::istream & is);
|
||||
|
||||
///
|
||||
void write(std::ostream & os) const;
|
||||
|
||||
/// Return lastcommands container (vector)
|
||||
LastCommands const getcommands() const { return lastcommands; }
|
||||
|
||||
/** add command to lastcommands list
|
||||
@param command command to add
|
||||
*/
|
||||
void add(std::string const & command);
|
||||
|
||||
/** clear lastcommands list
|
||||
*/
|
||||
void clear();
|
||||
|
||||
private:
|
||||
/// number of commands in the lastcommands list.
|
||||
unsigned int num_lastcommands;
|
||||
|
||||
/** Used by the constructor to set the number of stored last commands.
|
||||
@param num the number of lastcommands to set.
|
||||
*/
|
||||
void setNumberOfLastCommands(unsigned int num);
|
||||
|
||||
/// a list of lastopened commands
|
||||
LastCommands lastcommands;
|
||||
|
||||
/// Default number of lastcommands.
|
||||
unsigned int const default_num_last_commands;
|
||||
|
||||
/// Max number of lastcommands.
|
||||
unsigned int const absolute_max_last_commands;
|
||||
};
|
||||
|
||||
|
||||
class Session
|
||||
{
|
||||
public:
|
||||
/// Read the session file. @param num length of lastfiles
|
||||
explicit Session(unsigned int num = 4);
|
||||
explicit Session(unsigned int num_last_files = 4,
|
||||
unsigned int num_last_commands = 30);
|
||||
/// Write the session file.
|
||||
void writeFile() const;
|
||||
///
|
||||
@ -286,6 +335,10 @@ public:
|
||||
BookmarksSection & bookmarks() { return bookmarks_; }
|
||||
///
|
||||
BookmarksSection const & bookmarks() const { return bookmarks_; }
|
||||
///
|
||||
LastCommandsSection & lastCommands() { return last_commands; }
|
||||
///
|
||||
LastCommandsSection const & lastCommands() const { return last_commands; }
|
||||
|
||||
private:
|
||||
friend class LyX;
|
||||
@ -311,6 +364,8 @@ private:
|
||||
LastFilePosSection last_file_pos;
|
||||
///
|
||||
BookmarksSection bookmarks_;
|
||||
///
|
||||
LastCommandsSection last_commands;
|
||||
};
|
||||
|
||||
/// This is a singleton class. Get the instance.
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "LyXFunc.h"
|
||||
#include "LyXAction.h"
|
||||
#include "FuncRequest.h"
|
||||
#include "Session.h"
|
||||
|
||||
#include "support/lyxalgo.h"
|
||||
#include "support/lstrings.h"
|
||||
@ -54,14 +55,15 @@ public:
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
}
|
||||
protected:
|
||||
void mouseReleaseEvent(QMouseEvent * ev) {
|
||||
if (ev->x() < 0 || ev->y() < 0
|
||||
|| ev->x() > width() || ev->y() > height()) {
|
||||
bool event(QEvent * ev) {
|
||||
if (ev->type() == QEvent::MouseButtonPress) {
|
||||
QMouseEvent * me = static_cast<QMouseEvent *>(ev);
|
||||
if (me->x() < 0 || me->y() < 0
|
||||
|| me->x() > width() || me->y() > height())
|
||||
hide();
|
||||
} else {
|
||||
// emit signal
|
||||
itemPressed(currentItem());
|
||||
return true;
|
||||
}
|
||||
return QListWidget::event(ev);
|
||||
}
|
||||
|
||||
void keyPressEvent(QKeyEvent * ev) {
|
||||
@ -70,7 +72,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);
|
||||
}
|
||||
@ -80,7 +82,7 @@ protected:
|
||||
|
||||
|
||||
GuiCommandBuffer::GuiCommandBuffer(GuiView * view)
|
||||
: view_(view), history_pos_(history_.end())
|
||||
: view_(view)
|
||||
{
|
||||
transform(lyxaction.func_begin(), lyxaction.func_end(),
|
||||
back_inserter(commands_), firster());
|
||||
@ -91,13 +93,15 @@ GuiCommandBuffer::GuiCommandBuffer(GuiView * view)
|
||||
QVBoxLayout * top = new QVBoxLayout(this);
|
||||
QHBoxLayout * layout = new QHBoxLayout(0);
|
||||
|
||||
QPushButton * up = new QPushButton(qpup, "", this);
|
||||
up->setMaximumSize(24, 24);
|
||||
QPushButton * down = new QPushButton(qpdown, "", this);
|
||||
down->setToolTip(qt_("Next command"));
|
||||
down->setMaximumSize(24, 24);
|
||||
connect(down, SIGNAL(clicked()), this, SLOT(down()));
|
||||
connect(up, SIGNAL(clicked()), this, SLOT(up()));
|
||||
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());
|
||||
@ -110,13 +114,26 @@ GuiCommandBuffer::GuiCommandBuffer(GuiView * 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();
|
||||
}
|
||||
|
||||
|
||||
@ -133,7 +150,21 @@ void GuiCommandBuffer::dispatch()
|
||||
view_->setFocus();
|
||||
edit_->setText(QString());
|
||||
edit_->clearFocus();
|
||||
dispatch(fromqstr(cmd));
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@ -143,46 +174,50 @@ void GuiCommandBuffer::complete()
|
||||
string new_input;
|
||||
vector<string> comp = completions(input, new_input);
|
||||
|
||||
if (comp.empty() && new_input == input) {
|
||||
// show_info_suffix(qt_("[no match]"), input);
|
||||
return;
|
||||
}
|
||||
|
||||
if (comp.empty()) {
|
||||
if (new_input != input)
|
||||
edit_->setText(toqstr(new_input));
|
||||
// show_info_suffix(("[only completion]"), 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<string> 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<string>::const_iterator cit = comp.begin();
|
||||
vector<string>::const_iterator end = comp.end();
|
||||
vector<string>::const_iterator cit = list.begin();
|
||||
vector<string>::const_iterator end = list.end();
|
||||
if (!reversed) {
|
||||
for (; cit != end; ++cit)
|
||||
list->addItem(toqstr(*cit));
|
||||
listBox ->addItem(toqstr(*cit));
|
||||
} else {
|
||||
for (--end; end != cit; --end)
|
||||
listBox ->addItem(toqstr(*end));
|
||||
}
|
||||
|
||||
list->resize(list->sizeHint());
|
||||
QPoint const pos = edit_->mapToGlobal(QPoint(0, 0));
|
||||
listBox->resize(listBox ->sizeHint());
|
||||
|
||||
int const y = max(0, pos.y() - list->height());
|
||||
int const y = max(0, pos.y() - listBox->height());
|
||||
listBox->move(pos.x(), y);
|
||||
|
||||
list->move(pos.x(), y);
|
||||
connect(listBox, SIGNAL(itemClicked(QListWidgetItem *)),
|
||||
this, SLOT(item_selected(QListWidgetItem *)));
|
||||
connect(listBox, SIGNAL(itemActivated(QListWidgetItem *)),
|
||||
this, SLOT(item_selected(QListWidgetItem *)));
|
||||
|
||||
connect(list, SIGNAL(itemPressed(QListWidgetItem *)),
|
||||
this, SLOT(complete_selected(QListWidgetItem *)));
|
||||
connect(list, SIGNAL(itemActivated(QListWidgetItem *)),
|
||||
this, SLOT(complete_selected(QListWidgetItem *)));
|
||||
|
||||
list->show();
|
||||
list->setFocus();
|
||||
listBox->show();
|
||||
listBox->setFocus();
|
||||
}
|
||||
|
||||
|
||||
void GuiCommandBuffer::complete_selected(QListWidgetItem * item)
|
||||
void GuiCommandBuffer::item_selected(QListWidgetItem * item)
|
||||
{
|
||||
QWidget const * widget = static_cast<QWidget const *>(sender());
|
||||
const_cast<QWidget *>(widget)->hide();
|
||||
@ -197,11 +232,11 @@ void GuiCommandBuffer::up()
|
||||
string const input = fromqstr(edit_->text());
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
@ -210,11 +245,11 @@ void GuiCommandBuffer::down()
|
||||
string const input = fromqstr(edit_->text());
|
||||
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_pos_ != history_.end()-1);
|
||||
upPB->setEnabled(history_pos_ != history_.begin());
|
||||
}
|
||||
|
||||
|
||||
@ -317,8 +352,10 @@ void GuiCommandBuffer::dispatch(string const & str)
|
||||
if (str.empty())
|
||||
return;
|
||||
|
||||
history_.push_back(str);
|
||||
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;
|
||||
theLyXFunc().setLyXView(view_);
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "support/docstring.h"
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QWidget>
|
||||
|
||||
#include <vector>
|
||||
@ -42,8 +43,10 @@ public Q_SLOTS:
|
||||
void dispatch();
|
||||
/// tab-complete
|
||||
void complete();
|
||||
/// select-complete
|
||||
void complete_selected(QListWidgetItem *);
|
||||
/// show history
|
||||
void listHistoryUp();
|
||||
/// called when an item in a list is selected
|
||||
void item_selected(QListWidgetItem *);
|
||||
/// up
|
||||
void up();
|
||||
/// down
|
||||
@ -67,6 +70,11 @@ private:
|
||||
/// hide the command buffer.
|
||||
void hide() const;
|
||||
|
||||
/// open a listbox and show the contents of the list. When reversed
|
||||
/// is true, the contents of the list is filled bottom-up.
|
||||
void showList(std::vector<std::string> const & list,
|
||||
QPoint const & pos, bool reversed = false) const;
|
||||
|
||||
/// return the possible completions
|
||||
std::vector<std::string> const completions(std::string const & prefix,
|
||||
std::string & new_prefix);
|
||||
@ -82,6 +90,12 @@ private:
|
||||
|
||||
/// current position in command history
|
||||
std::vector<std::string>::const_iterator history_pos_;
|
||||
|
||||
/// the button up
|
||||
QPushButton * upPB;
|
||||
|
||||
/// the button down
|
||||
QPushButton * downPB;
|
||||
};
|
||||
|
||||
} // namespace frontend
|
||||
|
Loading…
Reference in New Issue
Block a user