mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 13:18:28 +00:00
I fixed the two bugs (Very shallow in fact)
Please test the minibuffer, and report things that are broken. I think things should still be working the same ... git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@4713 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
1d0eda5d02
commit
e225bbd75e
@ -1,3 +1,7 @@
|
||||
2002-07-19 John Levon <moz@compsoc.man.ac.uk>
|
||||
|
||||
* lyxfunc.C: move minibuffer completion handling out of here
|
||||
|
||||
2002-07-19 John Levon <moz@compsoc.man.ac.uk>
|
||||
|
||||
* BufferView_pimpl.C:
|
||||
|
@ -1,3 +1,12 @@
|
||||
2002-07-19 John Levon <moz@compsoc.man.ac.uk>
|
||||
|
||||
* LyXView.h:
|
||||
* LyXView.C: use ControlCommandBuffer, related
|
||||
cleanup
|
||||
|
||||
* MiniBuffer.h:
|
||||
* MiniBuffer.C: remove
|
||||
|
||||
2002-07-18 John Levon <moz@compsoc.man.ac.uk>
|
||||
|
||||
* LyXView.h:
|
||||
|
@ -14,7 +14,6 @@
|
||||
#endif
|
||||
|
||||
#include "LyXView.h"
|
||||
#include "MiniBuffer.h"
|
||||
#include "debug.h"
|
||||
#include "intl.h"
|
||||
#include "lyxrc.h"
|
||||
@ -28,10 +27,11 @@
|
||||
#include "bufferview_funcs.h"
|
||||
#include "lyxtextclasslist.h"
|
||||
|
||||
#include "frontends/Dialogs.h"
|
||||
#include "frontends/Toolbar.h"
|
||||
#include "frontends/Timeout.h"
|
||||
#include "frontends/Menubar.h"
|
||||
#include "Dialogs.h"
|
||||
#include "Toolbar.h"
|
||||
#include "Timeout.h"
|
||||
#include "Menubar.h"
|
||||
#include "controllers/ControlCommandBuffer.h"
|
||||
|
||||
#include "support/filetools.h" // OnlyFilename()
|
||||
|
||||
@ -56,6 +56,7 @@ LyXView::LyXView()
|
||||
autosave_timeout_.reset(new Timeout(5000));
|
||||
|
||||
dialogs_.reset(new Dialogs(this));
|
||||
controlcommand_.reset(new ControlCommandBuffer(*getLyXFunc()));
|
||||
}
|
||||
|
||||
|
||||
@ -115,18 +116,6 @@ LyXFunc * LyXView::getLyXFunc() const
|
||||
}
|
||||
|
||||
|
||||
MiniBuffer * LyXView::getMiniBuffer() const
|
||||
{
|
||||
return minibuffer_.get();
|
||||
}
|
||||
|
||||
|
||||
void LyXView::message(string const & str)
|
||||
{
|
||||
minibuffer_->message(str);
|
||||
}
|
||||
|
||||
|
||||
Menubar * LyXView::getMenubar() const
|
||||
{
|
||||
return menubar_.get();
|
||||
|
@ -26,9 +26,9 @@
|
||||
|
||||
class Buffer;
|
||||
class Toolbar;
|
||||
class MiniBuffer;
|
||||
class Intl;
|
||||
class Menubar;
|
||||
class ControlCommandBuffer;
|
||||
|
||||
class BufferView;
|
||||
class Dialogs;
|
||||
@ -85,11 +85,6 @@ public:
|
||||
/// return the menubar for this view
|
||||
Menubar * getMenubar() const;
|
||||
|
||||
/// return the minibuffer for this view
|
||||
/// FIXME: I'm not at all sure that LyXFunc should be
|
||||
/// aware of a mini buffer as such
|
||||
MiniBuffer * getMiniBuffer() const;
|
||||
|
||||
/// get access to the dialogs
|
||||
Dialogs * getDialogs() { return dialogs_.get(); }
|
||||
|
||||
@ -108,11 +103,14 @@ public:
|
||||
/// update the menubar
|
||||
void updateMenubar();
|
||||
|
||||
/// focus the command buffer (minibuffer)
|
||||
boost::signal0<void> focus_command_buffer;
|
||||
|
||||
/// view state string changed
|
||||
boost::signal0<void> view_state_changed;
|
||||
|
||||
/// display a message in the view
|
||||
void message(string const &);
|
||||
virtual void message(string const &) = 0;
|
||||
|
||||
/// updates the title of the window
|
||||
void updateWindowTitle();
|
||||
@ -128,8 +126,8 @@ protected:
|
||||
boost::scoped_ptr<Menubar> menubar_;
|
||||
/// view's toolbar
|
||||
boost::scoped_ptr<Toolbar> toolbar_;
|
||||
/// view's minibuffer
|
||||
boost::scoped_ptr<MiniBuffer> minibuffer_;
|
||||
/// view's command buffer controller
|
||||
boost::scoped_ptr<ControlCommandBuffer> controlcommand_;
|
||||
|
||||
/// keyboard mapping object
|
||||
boost::scoped_ptr<Intl> intl_;
|
||||
|
@ -30,8 +30,6 @@ libfrontends_la_SOURCES = \
|
||||
LyXView.h \
|
||||
Menubar.C \
|
||||
Menubar.h \
|
||||
MiniBuffer.C \
|
||||
MiniBuffer.h \
|
||||
Painter.C \
|
||||
Painter.h \
|
||||
Timeout.C \
|
||||
|
@ -1,116 +0,0 @@
|
||||
// -*- C++ -*-
|
||||
/**
|
||||
* \file MiniBuffer.C
|
||||
* Copyright 1995-2002 the LyX Team
|
||||
* Read the file COPYING
|
||||
*
|
||||
* \author Lars
|
||||
* \author Asger and Juergen
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#endif
|
||||
|
||||
#include "MiniBuffer.h"
|
||||
|
||||
#include "support/lyxalgo.h"
|
||||
#include "support/filetools.h"
|
||||
#include "support/lstrings.h"
|
||||
#include "frontends/LyXView.h"
|
||||
#include "gettext.h"
|
||||
#include "LyXAction.h"
|
||||
#include "BufferView.h"
|
||||
#include "frontends/Timeout.h"
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
using std::vector;
|
||||
using std::back_inserter;
|
||||
using std::find;
|
||||
|
||||
extern LyXAction lyxaction;
|
||||
|
||||
|
||||
MiniBuffer::MiniBuffer(LyXView * o)
|
||||
: information_displayed_(false), owner_(o)
|
||||
{
|
||||
timer = new Timeout(6000);
|
||||
timer->timeout.connect(boost::bind(&MiniBuffer::message_timeout, this));
|
||||
|
||||
information_timer_ = new Timeout(1500);
|
||||
information_timer_->timeout.connect(boost::bind(&MiniBuffer::restore_input, this));
|
||||
}
|
||||
|
||||
|
||||
MiniBuffer::~MiniBuffer()
|
||||
{
|
||||
delete timer;
|
||||
delete information_timer_;
|
||||
}
|
||||
|
||||
|
||||
void MiniBuffer::show_information(string const & info, string const & input)
|
||||
{
|
||||
stored_input = input;
|
||||
information_displayed_ = true;
|
||||
information_timer_->start();
|
||||
set_input(info);
|
||||
}
|
||||
|
||||
|
||||
void MiniBuffer::restore_input()
|
||||
{
|
||||
if (information_displayed_) {
|
||||
information_displayed_ = false;
|
||||
set_input(stored_input);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MiniBuffer::message(string const & str)
|
||||
{
|
||||
timer->restart();
|
||||
string const ntext = strip(str);
|
||||
if (! isEditingMode()) {
|
||||
set_input(ntext);
|
||||
text = ntext;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MiniBuffer::prepareForInput(vector<string> const & completion,
|
||||
vector<string> & history)
|
||||
{
|
||||
completion_ = completion;
|
||||
history_ = &history;
|
||||
hist_iter = history_->end();
|
||||
text.erase();
|
||||
set_input("");
|
||||
editingMode();
|
||||
}
|
||||
|
||||
|
||||
void MiniBuffer::message_timeout()
|
||||
{
|
||||
// If we have focus, we don't want to change anything.
|
||||
if (isEditingMode())
|
||||
return;
|
||||
|
||||
timeout();
|
||||
// we have redraw problems therefor we don't stop the
|
||||
// timer as so we force a redraw every 6 seconds.
|
||||
// timer->stop();
|
||||
}
|
||||
|
||||
|
||||
void MiniBuffer::set_complete_input(string const & str)
|
||||
{
|
||||
if (!str.empty()) {
|
||||
// add a space so the user can type
|
||||
// an argument immediately
|
||||
set_input(str + " ");
|
||||
}
|
||||
}
|
@ -1,133 +0,0 @@
|
||||
// -*- C++ -*-
|
||||
/**
|
||||
* \file MiniBuffer.h
|
||||
* Copyright 1995-2002 the LyX Team
|
||||
* Read the file COPYING
|
||||
*
|
||||
* \author Lars
|
||||
* \author Asger and Juergen
|
||||
*/
|
||||
|
||||
#ifndef MINIBUFFER_H
|
||||
#define MINIBUFFER_H
|
||||
|
||||
#include "LString.h"
|
||||
|
||||
#include <boost/signals/signal0.hpp>
|
||||
#include <boost/signals/signal1.hpp>
|
||||
#include <boost/signals/trackable.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
class LyXView;
|
||||
class Timeout;
|
||||
|
||||
///
|
||||
class MiniBuffer : public boost::signals::trackable {
|
||||
public:
|
||||
///
|
||||
MiniBuffer(LyXView *);
|
||||
|
||||
/// destructor
|
||||
virtual ~MiniBuffer();
|
||||
|
||||
/// Displays a text for 6 seconds
|
||||
void message(string const & str);
|
||||
|
||||
/** Makes the minibuffer wait for a string to be inserted.
|
||||
Waits for a string to be inserted into the minibuffer, when
|
||||
the string has been inserted the signal stringReady is
|
||||
emitted.
|
||||
*/
|
||||
void prepareForInput(std::vector<string> const & completion,
|
||||
std::vector<string> & history);
|
||||
|
||||
/// This is signalled when the user has input a string
|
||||
boost::signal1<void, string const &> inputReady;
|
||||
|
||||
/// This is signalled 6 seconds after a message has been displayed
|
||||
boost::signal0<void> timeout;
|
||||
|
||||
protected:
|
||||
/// Are we in editing mode?
|
||||
virtual bool isEditingMode() const = 0;
|
||||
/// enter editing mode
|
||||
virtual void editingMode() = 0;
|
||||
/// enter message display mode
|
||||
virtual void messageMode() = 0;
|
||||
|
||||
/**
|
||||
* This will show the info string for 1.5 seconds, after
|
||||
* which it will revert to the input string.
|
||||
* Use this in editing mode only. If the user presses a
|
||||
* key in the 1.5 second interval, the information will
|
||||
* disappear.
|
||||
*/
|
||||
void show_information(string const & info, string const & input);
|
||||
|
||||
/**
|
||||
* This is called after information has been shown for 1.5 seconds
|
||||
* to restore the input as given in the show_information call.
|
||||
*/
|
||||
void restore_input();
|
||||
|
||||
/**
|
||||
* This is called when we tab-completed a command and it adds
|
||||
* a space to the input so that we're ready to input any arguments.
|
||||
*/
|
||||
void set_complete_input(string const &);
|
||||
|
||||
/// set the minibuffer content in editing mode
|
||||
virtual void set_input(string const &) = 0;
|
||||
|
||||
/**
|
||||
* This when a message has been displayed for 6 seconds and
|
||||
* it will emit the timeout signal.
|
||||
*/
|
||||
void message_timeout();
|
||||
|
||||
/**
|
||||
* This will be the input after the information will timeout
|
||||
* in 1.5 seconds or we press a key and force the information
|
||||
* to disappear.
|
||||
*/
|
||||
string stored_input;
|
||||
|
||||
/**
|
||||
* This is true for 1.5 seconds while information is shown in
|
||||
* editing mode. If the user presses a key while information
|
||||
* is shown, the info will disappear.
|
||||
*/
|
||||
bool information_displayed_;
|
||||
|
||||
///
|
||||
LyXView * owner_;
|
||||
|
||||
/// This is the text for the message display
|
||||
string text;
|
||||
|
||||
/**
|
||||
* This will emit the timeout signal after a message has been
|
||||
* displayed for 6 seconds.
|
||||
*/
|
||||
Timeout * timer;
|
||||
|
||||
/**
|
||||
* This will call restore_input after 1.5 seconds to restore
|
||||
* the input after an information display.
|
||||
*/
|
||||
Timeout * information_timer_;
|
||||
|
||||
///
|
||||
std::vector<string> completion_;
|
||||
///
|
||||
std::vector<string> * history_;
|
||||
///
|
||||
std::vector<string>::iterator hist_iter;
|
||||
};
|
||||
|
||||
#endif // MINIBUFFER_H
|
@ -1,3 +1,10 @@
|
||||
2002-07-19 John Levon <moz@compsoc.man.ac.uk>
|
||||
|
||||
* Makefile.am:
|
||||
* ControlCommandBuffer.h:
|
||||
* ControlCommandBuffer.C: add controller for command (mini) buffer
|
||||
handling
|
||||
|
||||
2002-07-19 John Levon <moz@compsoc.man.ac.uk>
|
||||
|
||||
* ControlRef.C: fix dispatch call
|
||||
|
114
src/frontends/controllers/ControlCommandBuffer.C
Normal file
114
src/frontends/controllers/ControlCommandBuffer.C
Normal file
@ -0,0 +1,114 @@
|
||||
/**
|
||||
* \file ControlCommandBuffer.C
|
||||
* Copyright 1995-2002 the LyX Team
|
||||
* Read the file COPYING
|
||||
*
|
||||
* \author Lars
|
||||
* \author Asger and Juergen
|
||||
* \author John Levon <levon@movementarian.org>
|
||||
*/
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#endif
|
||||
|
||||
#include "ControlCommandBuffer.h"
|
||||
#include "support/lyxalgo.h"
|
||||
#include "support/lstrings.h"
|
||||
#include "LyXAction.h"
|
||||
#include "lyxfunc.h"
|
||||
#include "debug.h"
|
||||
|
||||
using std::vector;
|
||||
using std::back_inserter;
|
||||
using std::transform;
|
||||
using std::endl;
|
||||
|
||||
extern LyXAction lyxaction;
|
||||
|
||||
namespace {
|
||||
|
||||
struct prefix_p {
|
||||
string p;
|
||||
prefix_p(string const & s)
|
||||
: p(s) {}
|
||||
bool operator()(string const & s) const {
|
||||
return prefixIs(s, p);
|
||||
}
|
||||
};
|
||||
|
||||
} // end of anon namespace
|
||||
|
||||
|
||||
ControlCommandBuffer::ControlCommandBuffer(LyXFunc & lf)
|
||||
: lyxfunc_(lf), history_pos_(history_.end())
|
||||
{
|
||||
transform(lyxaction.func_begin(), lyxaction.func_end(),
|
||||
back_inserter(commands_), lyx::firster());
|
||||
}
|
||||
|
||||
|
||||
string const ControlCommandBuffer::historyUp()
|
||||
{
|
||||
if (history_pos_ == history_.begin())
|
||||
return "";
|
||||
|
||||
return *(--history_pos_);
|
||||
}
|
||||
|
||||
|
||||
string const ControlCommandBuffer::historyDown()
|
||||
{
|
||||
if (history_pos_ == history_.end())
|
||||
return "";
|
||||
if (history_pos_ + 1 == history_.end())
|
||||
return "";
|
||||
|
||||
return *(++history_pos_);
|
||||
}
|
||||
|
||||
|
||||
vector<string> const ControlCommandBuffer::completions(string const & prefix, string & new_prefix)
|
||||
{
|
||||
vector<string> comp;
|
||||
|
||||
lyx::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<string>();
|
||||
}
|
||||
|
||||
// find maximal avaliable prefix
|
||||
string const tmp = comp[0];
|
||||
string test(prefix);
|
||||
if (tmp.length() > test.length())
|
||||
test += tmp[test.length()];
|
||||
while (test.length() < tmp.length()) {
|
||||
vector<string> vtmp;
|
||||
lyx::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 ControlCommandBuffer::dispatch(string const & str)
|
||||
{
|
||||
history_.push_back(str);
|
||||
history_pos_ = history_.end();
|
||||
lyxfunc_.dispatch(str, true);
|
||||
}
|
63
src/frontends/controllers/ControlCommandBuffer.h
Normal file
63
src/frontends/controllers/ControlCommandBuffer.h
Normal file
@ -0,0 +1,63 @@
|
||||
// -*- C++ -*-
|
||||
/**
|
||||
* \file ControlCommandBuffer.h
|
||||
* Copyright 1995-2002 the LyX Team
|
||||
* Read the file COPYING
|
||||
*
|
||||
* \author Lars
|
||||
* \author Asger and Juergen
|
||||
* \author John Levon <levon@movementarian.org>
|
||||
*/
|
||||
|
||||
#ifndef CONTROLCOMMANDBUFFER_H
|
||||
#define CONTROLCOMMANDBUFFER_H
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "LString.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
class LyXFunc;
|
||||
|
||||
/**
|
||||
* ControlCommandBuffer
|
||||
*
|
||||
* This provides methods for the use of a toolkit's
|
||||
* minibuffer/command buffer
|
||||
*/
|
||||
class ControlCommandBuffer {
|
||||
public:
|
||||
ControlCommandBuffer(LyXFunc & lf);
|
||||
|
||||
/// return the previous history entry if any
|
||||
string const historyUp();
|
||||
|
||||
/// return the next history entry if any
|
||||
string const historyDown();
|
||||
|
||||
/// return the possible completions
|
||||
std::vector<string> const completions(string const & prefix, string & new_prefix);
|
||||
|
||||
/// dispatch a command
|
||||
void dispatch(string const & str);
|
||||
|
||||
private:
|
||||
/// controlling lyxfunc
|
||||
LyXFunc & lyxfunc_;
|
||||
|
||||
/// available command names
|
||||
std::vector<string> commands_;
|
||||
|
||||
/// command history
|
||||
std::vector<string> history_;
|
||||
|
||||
/// current position in command history
|
||||
std::vector<string>::const_iterator history_pos_;
|
||||
};
|
||||
|
||||
#endif // CONTROLCOMMANDBUFFER_H
|
@ -36,6 +36,8 @@ libcontrollers_la_SOURCES= \
|
||||
ControlCitation.h \
|
||||
ControlCommand.C \
|
||||
ControlCommand.h \
|
||||
ControlCommandBuffer.C \
|
||||
ControlCommandBuffer.h \
|
||||
ControlConnections.C \
|
||||
ControlConnections.h \
|
||||
ControlDialog.h \
|
||||
|
@ -1,3 +1,7 @@
|
||||
2002-07-19 John Levon <moz@compsoc.man.ac.uk>
|
||||
|
||||
* QWorkArea.C: remove unnecessary include
|
||||
|
||||
2002-07-18 John Levon <moz@compsoc.man.ac.uk>
|
||||
|
||||
* QtView.C:
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
#include "debug.h"
|
||||
#include "LyXView.h"
|
||||
#include "lyxrc.h" // lyxrc.show_banner
|
||||
#include "version.h" // lyx_version
|
||||
|
||||
#include "support/filetools.h" // LibFileSearch
|
||||
|
@ -1,3 +1,17 @@
|
||||
2002-07-19 John Levon <moz@compsoc.man.ac.uk>
|
||||
|
||||
* DropDown.h:
|
||||
* DropDown.C: remove unneeded LyXView *
|
||||
|
||||
* XFormsView.h:
|
||||
* XFormsView.C: changes for minibuffer rework
|
||||
|
||||
* XMiniBuffer.h:
|
||||
* XMiniBuffer.C: use ControlCommandBuffer. Move relevant
|
||||
old code to here
|
||||
|
||||
* lyx_gui.C: add FIXME
|
||||
|
||||
2002-07-19 John Levon <moz@compsoc.man.ac.uk>
|
||||
|
||||
* FormMathsDelim.C:
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include <iostream>
|
||||
#include <cctype>
|
||||
|
||||
|
||||
#ifndef CXX_GLOBAL_CSTD
|
||||
using std::isprint;
|
||||
#endif
|
||||
@ -46,8 +45,7 @@ extern "C" int C_PeekCB(FL_FORM * form, void *xev)
|
||||
} // namespace anon
|
||||
|
||||
|
||||
DropDown::DropDown(LyXView * lv, FL_OBJECT * ob)
|
||||
: lv_(lv)
|
||||
DropDown::DropDown(FL_OBJECT * ob)
|
||||
{
|
||||
form_ = fl_bgn_form(FL_NO_BOX, ob->w, 100);
|
||||
fl_add_box(FL_UP_BOX, 0, 0, ob->w, 100, "");
|
||||
|
@ -22,12 +22,10 @@
|
||||
#include "LString.h"
|
||||
#include <vector>
|
||||
|
||||
class LyXView;
|
||||
|
||||
class DropDown {
|
||||
public:
|
||||
/// constructor
|
||||
DropDown(LyXView * lv, FL_OBJECT * ob);
|
||||
DropDown(FL_OBJECT * ob);
|
||||
/// destructor
|
||||
~DropDown();
|
||||
|
||||
@ -56,9 +54,6 @@ private:
|
||||
/// move down a browser line
|
||||
void line_down();
|
||||
|
||||
/// owning lyxview
|
||||
LyXView * lv_;
|
||||
|
||||
/// our form
|
||||
FL_FORM * form_;
|
||||
|
||||
|
@ -19,7 +19,6 @@
|
||||
#if FL_VERSION < 1 && (FL_REVISION < 89 || (FL_REVISION == 89 && FL_FIXLEVEL < 5))
|
||||
#include "frontends/xforms/lyxlookup.h"
|
||||
#endif
|
||||
#include "frontends/MiniBuffer.h"
|
||||
#include "frontends/xforms/XMiniBuffer.h"
|
||||
#include "debug.h"
|
||||
#include "intl.h"
|
||||
@ -63,11 +62,8 @@ XFormsView::XFormsView(int width, int height)
|
||||
create_form_form_main(*getDialogs(), width, height);
|
||||
fl_set_form_atclose(getForm(), C_XFormsView_atCloseMainFormCB, 0);
|
||||
|
||||
// Connect the minibuffer signals
|
||||
minibuffer_->inputReady.connect(boost::bind(&XFormsView::dispatch, this, _1));
|
||||
|
||||
view_state_changed.connect(boost::bind(&XFormsView::show_view_state, this));
|
||||
minibuffer_->timeout.connect(boost::bind(&XFormsView::show_view_state, this));
|
||||
focus_command_buffer.connect(boost::bind(&XMiniBuffer::focus, minibuffer_.get()));
|
||||
|
||||
// Make sure the buttons are disabled if needed.
|
||||
updateToolbar();
|
||||
@ -77,25 +73,18 @@ XFormsView::XFormsView(int width, int height)
|
||||
|
||||
XFormsView::~XFormsView()
|
||||
{
|
||||
minibuffer_->freeze();
|
||||
fl_hide_form(form_);
|
||||
fl_free_form(form_);
|
||||
}
|
||||
|
||||
|
||||
void XFormsView::dispatch(string const & arg)
|
||||
{
|
||||
getLyXFunc()->dispatch(arg, true);
|
||||
}
|
||||
|
||||
|
||||
/// Redraw the main form.
|
||||
void XFormsView::redraw()
|
||||
{
|
||||
lyxerr[Debug::INFO] << "XFormsView::redraw()" << endl;
|
||||
fl_redraw_form(getForm());
|
||||
// This is dangerous, but we know it is safe
|
||||
XMiniBuffer * m = static_cast<XMiniBuffer *>(minibuffer_.get());
|
||||
m->redraw();
|
||||
minibuffer_->redraw();
|
||||
}
|
||||
|
||||
|
||||
@ -168,8 +157,8 @@ void XFormsView::create_form_form_main(Dialogs & dia, int width, int height)
|
||||
width - 3 * air, workheight));
|
||||
::current_view = bufferview_.get();
|
||||
|
||||
minibuffer_.reset(new XMiniBuffer(this, air, height - (25 + air),
|
||||
width - (2 * air), 25));
|
||||
minibuffer_.reset(new XMiniBuffer(this, *controlcommand_,
|
||||
air, height - (25 + air), width - (2 * air), 25));
|
||||
|
||||
// FIXME: why do this in xforms/ ?
|
||||
autosave_timeout_->timeout.connect(boost::bind(&XFormsView::autoSave, this));
|
||||
@ -195,8 +184,7 @@ void XFormsView::create_form_form_main(Dialogs & dia, int width, int height)
|
||||
|
||||
fl_end_form();
|
||||
|
||||
// This is dangerous, but we know it is safe in this situation
|
||||
static_cast<XMiniBuffer *>(minibuffer_.get())->dd_init();
|
||||
minibuffer_->dd_init();
|
||||
}
|
||||
|
||||
|
||||
@ -207,9 +195,15 @@ void XFormsView::setWindowTitle(string const & title, string const & icon_title)
|
||||
}
|
||||
|
||||
|
||||
void XFormsView::message(string const & str)
|
||||
{
|
||||
minibuffer_->message(str);
|
||||
}
|
||||
|
||||
|
||||
void XFormsView::show_view_state()
|
||||
{
|
||||
minibuffer_->message(getLyXFunc()->view_status_message());
|
||||
message(getLyXFunc()->view_status_message());
|
||||
}
|
||||
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "frontends/LyXView.h"
|
||||
|
||||
class Dialogs;
|
||||
class XMiniBuffer;
|
||||
|
||||
/**
|
||||
* XFormsView - xforms implementation of LyXView
|
||||
@ -54,8 +55,8 @@ public:
|
||||
/// callback for close event from window manager
|
||||
static int atCloseMainFormCB(FL_FORM *, void *);
|
||||
|
||||
/// dispatch an action
|
||||
void dispatch(string const & arg);
|
||||
/// display a status message
|
||||
virtual void message(string const & str);
|
||||
|
||||
private:
|
||||
/**
|
||||
@ -70,6 +71,8 @@ private:
|
||||
|
||||
/// makes the main form.
|
||||
void create_form_form_main(Dialogs & d, int width, int height);
|
||||
/// the minibuffer
|
||||
boost::scoped_ptr<XMiniBuffer> minibuffer_;
|
||||
/// the main form.
|
||||
FL_FORM * form_;
|
||||
};
|
||||
|
@ -16,46 +16,37 @@
|
||||
|
||||
#include "frontends/xforms/DropDown.h"
|
||||
#include "frontends/xforms/XFormsView.h"
|
||||
#include "frontends/controllers/ControlCommandBuffer.h"
|
||||
#include "frontends/Timeout.h"
|
||||
|
||||
#include "XMiniBuffer.h"
|
||||
#include "BufferView.h"
|
||||
#include "LyXAction.h"
|
||||
#include "gettext.h"
|
||||
#include "support/lyxalgo.h"
|
||||
#include "support/lstrings.h"
|
||||
#include "debug.h"
|
||||
#include "bufferview_funcs.h"
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <cctype>
|
||||
|
||||
#ifndef CXX_GLOBAL_CSTD
|
||||
using std::isprint;
|
||||
#endif
|
||||
|
||||
using std::endl;
|
||||
using std::vector;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
struct prefix {
|
||||
string p;
|
||||
prefix(string const & s)
|
||||
: p(s) {}
|
||||
bool operator()(string const & s) const {
|
||||
return prefixIs(s, p);
|
||||
}
|
||||
};
|
||||
|
||||
} // end of anon namespace
|
||||
|
||||
|
||||
XMiniBuffer::XMiniBuffer(LyXView * o, FL_Coord x, FL_Coord y,
|
||||
FL_Coord h, FL_Coord w)
|
||||
: MiniBuffer(o)
|
||||
XMiniBuffer::XMiniBuffer(XFormsView * v, ControlCommandBuffer & control,
|
||||
FL_Coord x, FL_Coord y, FL_Coord h, FL_Coord w)
|
||||
: controller_(control), view_(v),
|
||||
info_suffix_shown_(false)
|
||||
{
|
||||
create_input_box(FL_NORMAL_INPUT, x, y, h, w);
|
||||
input_obj_ = create_input_box(FL_NORMAL_INPUT, x, y, h, w);
|
||||
suffix_timer_.reset(new Timeout(1500));
|
||||
idle_timer_.reset(new Timeout(6000));
|
||||
suffix_timer_->timeout.connect(boost::bind(&XMiniBuffer::suffix_timeout, this));
|
||||
idle_timer_->timeout.connect(boost::bind(&XMiniBuffer::idle_timeout, this));
|
||||
idle_timer_->start();
|
||||
messageMode();
|
||||
}
|
||||
|
||||
@ -63,7 +54,7 @@ XMiniBuffer::XMiniBuffer(LyXView * o, FL_Coord x, FL_Coord y,
|
||||
// thanks for nothing, xforms (recursive creation not allowed)
|
||||
void XMiniBuffer::dd_init()
|
||||
{
|
||||
dropdown_ = new DropDown(owner_, the_buffer);
|
||||
dropdown_.reset(new DropDown(the_buffer_));
|
||||
dropdown_->result.connect(boost::bind(&XMiniBuffer::set_complete_input, this, _1));
|
||||
dropdown_->keypress.connect(boost::bind(&XMiniBuffer::append_char, this, _1));
|
||||
}
|
||||
@ -71,7 +62,6 @@ void XMiniBuffer::dd_init()
|
||||
|
||||
XMiniBuffer::~XMiniBuffer()
|
||||
{
|
||||
delete dropdown_;
|
||||
}
|
||||
|
||||
|
||||
@ -85,112 +75,86 @@ int XMiniBuffer::peek_event(FL_OBJECT * ob, int event,
|
||||
#endif
|
||||
|
||||
switch (event) {
|
||||
case FL_FOCUS:
|
||||
messageMode(false);
|
||||
break;
|
||||
case FL_UNFOCUS:
|
||||
messageMode();
|
||||
break;
|
||||
case FL_KEYBOARD:
|
||||
{
|
||||
string input;
|
||||
if (information_displayed_) {
|
||||
information_timer_->stop();
|
||||
input = stored_input;
|
||||
restore_input();
|
||||
} else {
|
||||
char const * tmp = fl_get_input(ob);
|
||||
input = tmp ? tmp : "";
|
||||
if (info_suffix_shown_) {
|
||||
suffix_timer_->stop();
|
||||
suffix_timeout();
|
||||
}
|
||||
|
||||
char const * tmp = fl_get_input(ob);
|
||||
input = tmp ? tmp : "";
|
||||
|
||||
switch (key) {
|
||||
case XK_Down:
|
||||
#ifdef XK_KP_Down
|
||||
case XK_KP_Down:
|
||||
#endif
|
||||
if (hist_iter != history_->end()) {
|
||||
++hist_iter;
|
||||
}
|
||||
if (hist_iter == history_->end()) {
|
||||
// no further history
|
||||
show_information(_("[End of history]"), input);
|
||||
{
|
||||
string const h(controller_.historyDown());
|
||||
if (h.empty()) {
|
||||
show_info_suffix(_("[End of history]"), input);
|
||||
} else {
|
||||
set_input((*hist_iter));
|
||||
set_input(h);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
case XK_Up:
|
||||
#ifdef XK_KP_Up
|
||||
case XK_KP_Up:
|
||||
#endif
|
||||
if (hist_iter == history_->begin()) {
|
||||
// no further history
|
||||
show_information(_("[Beginning of history]"),
|
||||
input);
|
||||
{
|
||||
string const h(controller_.historyUp());
|
||||
if (h.empty()) {
|
||||
show_info_suffix(_("[Beginning of history]"), input);
|
||||
} else {
|
||||
--hist_iter;
|
||||
set_input((*hist_iter));
|
||||
set_input(h);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
case 9:
|
||||
case XK_Tab:
|
||||
{
|
||||
// Completion handling.
|
||||
string new_input;
|
||||
vector<string> comp = controller_.completions(input, new_input);
|
||||
|
||||
vector<string> comp;
|
||||
lyx::copy_if(completion_.begin(),
|
||||
completion_.end(),
|
||||
back_inserter(comp), prefix(input));
|
||||
if (comp.empty() && new_input == input) {
|
||||
show_info_suffix(_("[no match]"), input);
|
||||
break;
|
||||
}
|
||||
|
||||
if (comp.empty()) {
|
||||
// No matches
|
||||
string const tmp = input + _(" [no match]");
|
||||
show_information(tmp, input);
|
||||
} else if (comp.size() == 1) {
|
||||
// Perfect match
|
||||
string const tmp =
|
||||
comp[0] + _(" [sole completion]");
|
||||
show_information(tmp, comp[0] + " ");
|
||||
} else {
|
||||
// More that one match
|
||||
// Find maximal avaliable prefix
|
||||
string const tmp = comp[0];
|
||||
string test(input);
|
||||
if (tmp.length() > test.length())
|
||||
test += tmp[test.length()];
|
||||
while (test.length() < tmp.length()) {
|
||||
vector<string> vtmp;
|
||||
lyx::copy_if(comp.begin(),
|
||||
comp.end(),
|
||||
back_inserter(vtmp),
|
||||
prefix(test));
|
||||
if (vtmp.size() != comp.size()) {
|
||||
test.erase(test.length() - 1);
|
||||
break;
|
||||
}
|
||||
test += tmp[test.length()];
|
||||
}
|
||||
set_input(test);
|
||||
|
||||
int x,y,w,h;
|
||||
fl_get_wingeometry(fl_get_real_object_window(the_buffer),
|
||||
&x, &y, &w, &h);
|
||||
|
||||
// asynchronous completion
|
||||
int const air = the_buffer->x;
|
||||
x += air;
|
||||
y += h - (the_buffer->h + air);
|
||||
w = the_buffer->w;
|
||||
dropdown_->select(comp, x, y, w);
|
||||
set_input(new_input);
|
||||
show_info_suffix(("[only completion]"), new_input + " ");
|
||||
break;
|
||||
}
|
||||
|
||||
set_input(new_input);
|
||||
|
||||
int x,y,w,h;
|
||||
fl_get_wingeometry(fl_get_real_object_window(the_buffer_),
|
||||
&x, &y, &w, &h);
|
||||
|
||||
// asynchronous completion
|
||||
int const air = the_buffer_->x;
|
||||
x += air;
|
||||
y += h - (the_buffer_->h + air);
|
||||
w = the_buffer_->w;
|
||||
dropdown_->select(comp, x, y, w);
|
||||
return 1;
|
||||
}
|
||||
case 27:
|
||||
case XK_Escape:
|
||||
// Abort
|
||||
#if 0
|
||||
owner_->view()->focus(true);
|
||||
#endif
|
||||
message_timeout();
|
||||
messageMode();
|
||||
//escape.emit();
|
||||
return 1;
|
||||
case 13:
|
||||
case XK_Return:
|
||||
@ -210,18 +174,12 @@ int XMiniBuffer::peek_event(FL_OBJECT * ob, int event,
|
||||
if (cit == completion_.end()) {
|
||||
// no such func/item
|
||||
string const tmp = input + _(" [no match]");
|
||||
show_information(tmp, input);
|
||||
show_info_suffix(tmp, input);
|
||||
} else {
|
||||
#endif
|
||||
// Return the inputted string
|
||||
messageMode();
|
||||
#if 0
|
||||
owner_->view()->focus(true);
|
||||
#endif
|
||||
if (!input.empty()) {
|
||||
history_->push_back(input);
|
||||
}
|
||||
inputReady(input);
|
||||
messageMode();
|
||||
redraw();
|
||||
controller_.dispatch(input);
|
||||
# if 0
|
||||
}
|
||||
#endif
|
||||
@ -232,7 +190,6 @@ int XMiniBuffer::peek_event(FL_OBJECT * ob, int event,
|
||||
}
|
||||
}
|
||||
default:
|
||||
//lyxerr << "Unhandled minibuffer event!" << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -251,7 +208,6 @@ extern "C" {
|
||||
return mini->peek_event(ob, event, key,
|
||||
static_cast<XEvent *>(xev));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -260,7 +216,7 @@ FL_OBJECT * XMiniBuffer::create_input_box(int type, FL_Coord x, FL_Coord y,
|
||||
{
|
||||
FL_OBJECT * obj;
|
||||
|
||||
the_buffer = obj = fl_add_input(type, x, y, w, h, text.c_str());
|
||||
the_buffer_ = obj = fl_add_input(type, x, y, w, h, "");
|
||||
fl_set_object_boxtype(obj, FL_DOWN_BOX);
|
||||
fl_set_object_resize(obj, FL_RESIZE_ALL);
|
||||
fl_set_object_gravity(obj, SouthWestGravity, SouthEastGravity);
|
||||
@ -272,37 +228,67 @@ FL_OBJECT * XMiniBuffer::create_input_box(int type, FL_Coord x, FL_Coord y,
|
||||
obj->u_vdata = this;
|
||||
obj->wantkey = FL_KEY_TAB;
|
||||
|
||||
set_input(text);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
void XMiniBuffer::freeze()
|
||||
{
|
||||
// we must prevent peek_event, or we get an unfocus() when the
|
||||
// containing form gets destroyed
|
||||
fl_set_object_prehandler(input_obj_, 0);
|
||||
}
|
||||
|
||||
|
||||
void XMiniBuffer::show_info_suffix(string const & suffix, string const & input)
|
||||
{
|
||||
stored_input_ = input;
|
||||
info_suffix_shown_ = true;
|
||||
set_input(input + " " + suffix);
|
||||
suffix_timer_->start();
|
||||
}
|
||||
|
||||
|
||||
void XMiniBuffer::idle_timeout()
|
||||
{
|
||||
set_input(currentState(view_->view()));
|
||||
}
|
||||
|
||||
|
||||
void XMiniBuffer::suffix_timeout()
|
||||
{
|
||||
info_suffix_shown_ = false;
|
||||
set_input(stored_input_);
|
||||
}
|
||||
|
||||
|
||||
bool XMiniBuffer::isEditingMode() const
|
||||
{
|
||||
return the_buffer->focus;
|
||||
return the_buffer_->focus;
|
||||
}
|
||||
|
||||
|
||||
void XMiniBuffer::editingMode()
|
||||
void XMiniBuffer::messageMode(bool on)
|
||||
{
|
||||
fl_activate_object(the_buffer);
|
||||
fl_set_focus_object(static_cast<XFormsView *>(owner_)->getForm(),
|
||||
the_buffer);
|
||||
redraw();
|
||||
}
|
||||
|
||||
|
||||
void XMiniBuffer::messageMode()
|
||||
{
|
||||
fl_deactivate_object(the_buffer);
|
||||
redraw();
|
||||
set_input("");
|
||||
if (!on) {
|
||||
fl_activate_object(the_buffer_);
|
||||
fl_set_focus_object(view_->getForm(), the_buffer_);
|
||||
redraw();
|
||||
idle_timer_->stop();
|
||||
} else {
|
||||
if (isEditingMode()) {
|
||||
// focus back to the workarea
|
||||
fl_set_focus_object(view_->getForm(), 0);
|
||||
idle_timer_->start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void XMiniBuffer::redraw()
|
||||
{
|
||||
fl_redraw_object(the_buffer);
|
||||
fl_redraw_object(the_buffer_);
|
||||
XFlush(fl_display);
|
||||
}
|
||||
|
||||
@ -312,16 +298,33 @@ void XMiniBuffer::append_char(char c)
|
||||
if (!c || !isprint(c))
|
||||
return;
|
||||
|
||||
char const * tmp = fl_get_input(the_buffer);
|
||||
char const * tmp = fl_get_input(the_buffer_);
|
||||
string str = tmp ? tmp : "";
|
||||
|
||||
str += c;
|
||||
|
||||
fl_set_input(the_buffer, str.c_str());
|
||||
fl_set_input(the_buffer_, str.c_str());
|
||||
}
|
||||
|
||||
|
||||
void XMiniBuffer::set_complete_input(string const & str)
|
||||
{
|
||||
if (!str.empty()) {
|
||||
// add a space so the user can type
|
||||
// an argument immediately
|
||||
set_input(str + " ");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void XMiniBuffer::message(string const & str)
|
||||
{
|
||||
if (!isEditingMode())
|
||||
set_input(str);
|
||||
}
|
||||
|
||||
|
||||
void XMiniBuffer::set_input(string const & str)
|
||||
{
|
||||
fl_set_input(the_buffer, str.c_str());
|
||||
fl_set_input(the_buffer_, str.c_str());
|
||||
}
|
||||
|
@ -6,47 +6,59 @@
|
||||
*
|
||||
* \author Lars
|
||||
* \author Asger and Juergen
|
||||
* \author John Levon <levon@movementarian.org>
|
||||
*/
|
||||
|
||||
#ifndef XMINIBUFFER_H
|
||||
#define XMINIBUFFER_H
|
||||
|
||||
#include "frontends/MiniBuffer.h"
|
||||
|
||||
#include FORMS_H_LOCATION
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
class DropDown;
|
||||
class ControlCommandBuffer;
|
||||
class Timeout;
|
||||
|
||||
///
|
||||
class XMiniBuffer : public MiniBuffer {
|
||||
/// in xforms, the minibuffer is both a status bar and a command buffer
|
||||
class XMiniBuffer {
|
||||
public:
|
||||
///
|
||||
XMiniBuffer(LyXView * o,
|
||||
XMiniBuffer(XFormsView * o, ControlCommandBuffer & control,
|
||||
FL_Coord x, FL_Coord y, FL_Coord h, FL_Coord w);
|
||||
|
||||
/// destructor
|
||||
~XMiniBuffer();
|
||||
|
||||
/// create drop down
|
||||
void dd_init();
|
||||
|
||||
///
|
||||
/// repaint the minibuffer
|
||||
void redraw();
|
||||
|
||||
///
|
||||
/// command completion, history, etc. management
|
||||
int peek_event(FL_OBJECT *, int, int, XEvent * xev);
|
||||
|
||||
/// show a message
|
||||
void message(string const & str);
|
||||
|
||||
/// focus the buffer for editing mode
|
||||
void focus() { messageMode(false); }
|
||||
|
||||
/// disable event management
|
||||
void freeze();
|
||||
|
||||
protected:
|
||||
/// Are we in editing mode?
|
||||
virtual bool isEditingMode() const;
|
||||
/// enter editing mode
|
||||
virtual void editingMode();
|
||||
/// enter message display mode
|
||||
virtual void messageMode();
|
||||
bool isEditingMode() const;
|
||||
|
||||
/// reset buffer to stored input text
|
||||
void suffix_timeout();
|
||||
|
||||
/// go back to "at rest" message
|
||||
void idle_timeout();
|
||||
|
||||
/**
|
||||
* Append "c" to the current input contents when the completion
|
||||
@ -54,16 +66,47 @@ protected:
|
||||
*/
|
||||
void append_char(char c);
|
||||
|
||||
/// completion selection callback
|
||||
void set_complete_input(string const & str);
|
||||
|
||||
/// set the minibuffer content in editing mode
|
||||
virtual void set_input(string const &);
|
||||
void set_input(string const &);
|
||||
|
||||
/// This creates the input widget for the minibuffer
|
||||
FL_OBJECT * create_input_box(int, FL_Coord, FL_Coord, FL_Coord, FL_Coord);
|
||||
|
||||
/// go into message mode
|
||||
void messageMode(bool on = true);
|
||||
|
||||
/// show a temporary message whilst in edit mode
|
||||
void show_info_suffix(string const & suffix, string const & input);
|
||||
|
||||
/// the dropdown menu
|
||||
DropDown * dropdown_;
|
||||
boost::scoped_ptr<DropDown> dropdown_;
|
||||
|
||||
/// info suffix timer
|
||||
boost::scoped_ptr<Timeout> suffix_timer_;
|
||||
|
||||
/// idle timer
|
||||
boost::scoped_ptr<Timeout> idle_timer_;
|
||||
|
||||
/// This is the input widget object
|
||||
FL_OBJECT * the_buffer;
|
||||
FL_OBJECT * the_buffer_;
|
||||
|
||||
/// the input box
|
||||
FL_OBJECT * input_obj_;
|
||||
|
||||
/// the controller we use
|
||||
ControlCommandBuffer & controller_;
|
||||
|
||||
/// the lyx view
|
||||
XFormsView * view_;
|
||||
|
||||
/// stored input when showing suffix info
|
||||
string stored_input_;
|
||||
|
||||
/// are we showing an informational suffix of the mesage ?
|
||||
bool info_suffix_shown_;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // XMINIBUFFER_H
|
||||
|
@ -304,7 +304,7 @@ void lyx_gui::start(string const & batch, vector<string> files)
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME
|
||||
// FIXME: breaks emergencyCleanup
|
||||
delete lyxserver;
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include "trans_mgr.h"
|
||||
#include "layout.h"
|
||||
#include "bufferview_funcs.h"
|
||||
#include "frontends/MiniBuffer.h"
|
||||
#include "frontends/LyXView.h"
|
||||
#include "frontends/lyx_gui.h"
|
||||
#include "vspace.h"
|
||||
@ -914,14 +913,8 @@ void LyXFunc::dispatch(kb_action action, string argument, bool verbose)
|
||||
|
||||
// --- Misc -------------------------------------------
|
||||
case LFUN_EXEC_COMMAND:
|
||||
{
|
||||
vector<string> allCmds;
|
||||
transform(lyxaction.func_begin(), lyxaction.func_end(),
|
||||
back_inserter(allCmds), lyx::firster());
|
||||
static vector<string> hist;
|
||||
owner->getMiniBuffer()->prepareForInput(allCmds, hist);
|
||||
}
|
||||
break;
|
||||
owner->focus_command_buffer();
|
||||
break;
|
||||
|
||||
case LFUN_CANCEL: // RVDK_PATCH_5
|
||||
keyseq.reset();
|
||||
@ -1370,10 +1363,10 @@ void LyXFunc::dispatch(kb_action action, string argument, bool verbose)
|
||||
|
||||
// passthrough hat and underscore outside mathed:
|
||||
case LFUN_SUBSCRIPT:
|
||||
dispatch(LFUN_SELFINSERT, "_");
|
||||
dispatch(LFUN_SELFINSERT, string("_"));
|
||||
break;
|
||||
case LFUN_SUPERSCRIPT:
|
||||
dispatch(LFUN_SELFINSERT, "^");
|
||||
dispatch(LFUN_SELFINSERT, string("^"));
|
||||
break;
|
||||
|
||||
case LFUN_MATH_PANEL:
|
||||
|
Loading…
Reference in New Issue
Block a user