Transfer all keyboard related code and actions from LyXFunc to GuiApplication. Part of it should be transfered later to GuiView and BufferView. This code can probably be simplified a lot...

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@31518 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Abdelrazak Younes 2009-10-04 20:58:20 +00:00
parent 19dd4f4583
commit 1cd45c2ae1
9 changed files with 299 additions and 317 deletions

View File

@ -765,8 +765,6 @@ bool LyX::init()
// load user bind file user.bind // load user bind file user.bind
pimpl_->toplevel_keymap_.read("user", 0, KeyMap::MissingOK); pimpl_->toplevel_keymap_.read("user", 0, KeyMap::MissingOK);
pimpl_->lyxfunc_.initKeySequences(&pimpl_->toplevel_keymap_);
if (lyxerr.debugging(Debug::LYXRC)) if (lyxerr.debugging(Debug::LYXRC))
lyxrc.print(); lyxrc.print();

View File

@ -40,10 +40,8 @@
#include "FuncRequest.h" #include "FuncRequest.h"
#include "FuncStatus.h" #include "FuncStatus.h"
#include "InsetIterator.h" #include "InsetIterator.h"
#include "Intl.h"
#include "KeyMap.h" #include "KeyMap.h"
#include "Language.h" #include "Language.h"
#include "LaTeXFeatures.h"
#include "Lexer.h" #include "Lexer.h"
#include "LyXAction.h" #include "LyXAction.h"
#include "lyxfind.h" #include "lyxfind.h"
@ -54,7 +52,6 @@
#include "ParagraphParameters.h" #include "ParagraphParameters.h"
#include "ParIterator.h" #include "ParIterator.h"
#include "Row.h" #include "Row.h"
#include "Server.h"
#include "Session.h" #include "Session.h"
#include "SpellChecker.h" #include "SpellChecker.h"
@ -71,9 +68,7 @@
#include "support/gettext.h" #include "support/gettext.h"
#include "support/lassert.h" #include "support/lassert.h"
#include "support/lstrings.h" #include "support/lstrings.h"
#include "support/Path.h"
#include "support/Package.h" #include "support/Package.h"
#include "support/Systemcall.h"
#include "support/convert.h" #include "support/convert.h"
#include "support/os.h" #include "support/os.h"
@ -89,81 +84,11 @@ using frontend::LyXView;
namespace Alert = frontend::Alert; namespace Alert = frontend::Alert;
namespace {
// This function runs "configure" and then rereads lyx.defaults to
// reconfigure the automatic settings.
void reconfigure(LyXView * lv, string const & option)
{
// emit message signal.
if (lv)
lv->message(_("Running configure..."));
// Run configure in user lyx directory
PathChanger p(package().user_support());
string configure_command = package().configure_command();
configure_command += option;
Systemcall one;
int ret = one.startscript(Systemcall::Wait, configure_command);
p.pop();
// emit message signal.
if (lv)
lv->message(_("Reloading configuration..."));
lyxrc.read(libFileSearch(string(), "lyxrc.defaults"));
// Re-read packages.lst
LaTeXFeatures::getAvailable();
if (ret)
Alert::information(_("System reconfiguration failed"),
_("The system reconfiguration has failed.\n"
"Default textclass is used but LyX may "
"not be able to work properly.\n"
"Please reconfigure again if needed."));
else
Alert::information(_("System reconfigured"),
_("The system has been reconfigured.\n"
"You need to restart LyX to make use of any\n"
"updated document class specifications."));
}
}
LyXFunc::LyXFunc() LyXFunc::LyXFunc()
: encoded_last_key(0), meta_fake_bit(NoModifier)
{ {
} }
void LyXFunc::initKeySequences(KeyMap * kb)
{
keyseq = KeySequence(kb, kb);
cancel_meta_seq = KeySequence(kb, kb);
}
void LyXFunc::handleKeyFunc(FuncCode action)
{
char_type c = encoded_last_key;
if (keyseq.length())
c = 0;
LyXView * lv = theApp()->currentWindow();
LASSERT(lv && lv->currentBufferView(), /**/);
BufferView * bv = lv->currentBufferView();
bv->getIntl().getTransManager().deadkey(
c, get_accent(action).accent, bv->cursor().innerText(),
bv->cursor());
// Need to clear, in case the minibuffer calls these
// actions
keyseq.clear();
// copied verbatim from do_accent_char
bv->cursor().resetAnchor();
bv->processUpdateFlags(Update::FitCursor);
}
//FIXME: bookmark handling is a frontend issue. This code should be transferred //FIXME: bookmark handling is a frontend issue. This code should be transferred
// to GuiView and be GuiView and be window dependent. // to GuiView and be GuiView and be window dependent.
void LyXFunc::gotoBookmark(unsigned int idx, bool openFile, bool switchToBuffer) void LyXFunc::gotoBookmark(unsigned int idx, bool openFile, bool switchToBuffer)
@ -226,105 +151,6 @@ void LyXFunc::gotoBookmark(unsigned int idx, bool openFile, bool switchToBuffer)
} }
void LyXFunc::processKeySym(KeySymbol const & keysym, KeyModifier state)
{
LYXERR(Debug::KEY, "KeySym is " << keysym.getSymbolName());
LyXView * lv = theApp()->currentWindow();
// Do nothing if we have nothing (JMarc)
if (!keysym.isOK()) {
LYXERR(Debug::KEY, "Empty kbd action (probably composing)");
lv->restartCursor();
return;
}
if (keysym.isModifier()) {
LYXERR(Debug::KEY, "isModifier true");
if (lv)
lv->restartCursor();
return;
}
//Encoding const * encoding = lv->documentBufferView()->cursor().getEncoding();
//encoded_last_key = keysym.getISOEncoded(encoding ? encoding->name() : "");
// FIXME: encoded_last_key shadows the member variable of the same
// name. Is that intended?
char_type encoded_last_key = keysym.getUCSEncoded();
// Do a one-deep top-level lookup for
// cancel and meta-fake keys. RVDK_PATCH_5
cancel_meta_seq.reset();
FuncRequest func = cancel_meta_seq.addkey(keysym, state);
LYXERR(Debug::KEY, "action first set to [" << func.action << ']');
// When not cancel or meta-fake, do the normal lookup.
// Note how the meta_fake Mod1 bit is OR-ed in and reset afterwards.
// Mostly, meta_fake_bit = NoModifier. RVDK_PATCH_5.
if ((func.action != LFUN_CANCEL) && (func.action != LFUN_META_PREFIX)) {
// remove Caps Lock and Mod2 as a modifiers
func = keyseq.addkey(keysym, (state | meta_fake_bit));
LYXERR(Debug::KEY, "action now set to [" << func.action << ']');
}
// Dont remove this unless you know what you are doing.
meta_fake_bit = NoModifier;
// Can this happen now ?
if (func.action == LFUN_NOACTION)
func = FuncRequest(LFUN_COMMAND_PREFIX);
LYXERR(Debug::KEY, " Key [action=" << func.action << "]["
<< keyseq.print(KeySequence::Portable) << ']');
// already here we know if it any point in going further
// why not return already here if action == -1 and
// num_bytes == 0? (Lgb)
if (keyseq.length() > 1)
lv->message(keyseq.print(KeySequence::ForGui));
// Maybe user can only reach the key via holding down shift.
// Let's see. But only if shift is the only modifier
if (func.action == LFUN_UNKNOWN_ACTION && state == ShiftModifier) {
LYXERR(Debug::KEY, "Trying without shift");
func = keyseq.addkey(keysym, NoModifier);
LYXERR(Debug::KEY, "Action now " << func.action);
}
if (func.action == LFUN_UNKNOWN_ACTION) {
// Hmm, we didn't match any of the keysequences. See
// if it's normal insertable text not already covered
// by a binding
if (keysym.isText() && keyseq.length() == 1) {
LYXERR(Debug::KEY, "isText() is true, inserting.");
func = FuncRequest(LFUN_SELF_INSERT,
FuncRequest::KEYBOARD);
} else {
LYXERR(Debug::KEY, "Unknown, !isText() - giving up");
lv->message(_("Unknown function."));
lv->restartCursor();
return;
}
}
if (func.action == LFUN_SELF_INSERT) {
if (encoded_last_key != 0) {
docstring const arg(1, encoded_last_key);
dispatch(FuncRequest(LFUN_SELF_INSERT, arg,
FuncRequest::KEYBOARD));
LYXERR(Debug::KEY, "SelfInsert arg[`" << to_utf8(arg) << "']");
}
} else {
dispatch(func);
if (!lv)
return;
}
}
FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const
{ {
//lyxerr << "LyXFunc::getStatus: cmd: " << cmd << endl; //lyxerr << "LyXFunc::getStatus: cmd: " << cmd << endl;
@ -431,19 +257,12 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const
break; break;
} }
case LFUN_COMMAND_PREFIX:
case LFUN_CANCEL:
case LFUN_META_PREFIX:
case LFUN_RECONFIGURE:
case LFUN_DROP_LAYOUTS_CHOICE: case LFUN_DROP_LAYOUTS_CHOICE:
case LFUN_SERVER_GET_FILENAME:
case LFUN_SERVER_NOTIFY:
case LFUN_CURSOR_FOLLOWS_SCROLLBAR_TOGGLE: case LFUN_CURSOR_FOLLOWS_SCROLLBAR_TOGGLE:
case LFUN_REPEAT: case LFUN_REPEAT:
case LFUN_PREFERENCES_SAVE: case LFUN_PREFERENCES_SAVE:
case LFUN_INSET_EDIT: case LFUN_INSET_EDIT:
case LFUN_BUFFER_SAVE_AS_DEFAULT: case LFUN_BUFFER_SAVE_AS_DEFAULT:
case LFUN_LYXRC_APPLY:
// these are handled in our dispatch() // these are handled in our dispatch()
break; break;
@ -564,44 +383,6 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
} else { } else {
switch (action) { switch (action) {
case LFUN_COMMAND_PREFIX:
dispatch(FuncRequest(LFUN_MESSAGE, keyseq.printOptions(true)));
break;
case LFUN_CANCEL:
keyseq.reset();
meta_fake_bit = NoModifier;
if (lv && lv->currentBufferView())
// cancel any selection
dispatch(FuncRequest(LFUN_MARK_OFF));
setMessage(from_ascii(N_("Cancel")));
break;
case LFUN_META_PREFIX:
meta_fake_bit = AltModifier;
setMessage(keyseq.print(KeySequence::ForGui));
break;
// --- Menus -----------------------------------------------
case LFUN_RECONFIGURE:
// argument is any additional parameter to the configure.py command
reconfigure(lv, argument);
break;
// --- lyxserver commands ----------------------------
case LFUN_SERVER_GET_FILENAME: {
LASSERT(lv && lv->documentBufferView(), return);
docstring const fname = from_utf8(
lv->documentBufferView()->buffer().absFileName());
setMessage(fname);
LYXERR(Debug::INFO, "FNAME[" << fname << ']');
break;
}
case LFUN_SERVER_NOTIFY:
dispatch_buffer = keyseq.print(KeySequence::Portable);
theServer().notifyClient(to_utf8(dispatch_buffer));
break;
case LFUN_CURSOR_FOLLOWS_SCROLLBAR_TOGGLE: case LFUN_CURSOR_FOLLOWS_SCROLLBAR_TOGGLE:
lyxrc.cursor_follows_scrollbar = !lyxrc.cursor_follows_scrollbar; lyxrc.cursor_follows_scrollbar = !lyxrc.cursor_follows_scrollbar;
break; break;
@ -714,36 +495,6 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
break; break;
} }
case LFUN_LYXRC_APPLY: {
// reset active key sequences, since the bindings
// are updated (bug 6064)
keyseq.reset();
LyXRC const lyxrc_orig = lyxrc;
istringstream ss(argument);
bool const success = lyxrc.read(ss) == 0;
if (!success) {
lyxerr << "Warning in LFUN_LYXRC_APPLY!\n"
<< "Unable to read lyxrc data"
<< endl;
break;
}
actOnUpdatedPrefs(lyxrc_orig, lyxrc);
setSpellChecker();
theApp()->resetGui();
/// We force the redraw in any case because there might be
/// some screen font changes.
/// FIXME: only the current view will be updated. the Gui
/// class is able to furnish the list of views.
updateFlags = Update::Force;
break;
}
case LFUN_BOOKMARK_GOTO: case LFUN_BOOKMARK_GOTO:
// go to bookmark, open unopened file and switch to buffer if necessary // go to bookmark, open unopened file and switch to buffer if necessary
gotoBookmark(convert<unsigned int>(to_utf8(cmd.argument())), true, true); gotoBookmark(convert<unsigned int>(to_utf8(cmd.argument())), true, true);
@ -755,11 +506,14 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
break; break;
default: default:
DispatchResult dr;
LASSERT(theApp(), /**/); LASSERT(theApp(), /**/);
// Let the frontend dispatch its own actions. // Let the frontend dispatch its own actions.
if (theApp()->dispatch(cmd)) theApp()->dispatch(cmd, dr);
if (dr.dispatched())
// Nothing more to do. // Nothing more to do.
return; break;
// Everything below is only for active window // Everything below is only for active window
if (lv == 0) if (lv == 0)
@ -791,7 +545,6 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
} }
// OK, so try the current Buffer itself... // OK, so try the current Buffer itself...
DispatchResult dr;
bv->buffer().dispatch(cmd, dr); bv->buffer().dispatch(cmd, dr);
if (dr.dispatched()) { if (dr.dispatched()) {
updateFlags = dr.update(); updateFlags = dr.update();
@ -901,28 +654,4 @@ void LyXFunc::setMessage(docstring const & m) const
} }
docstring LyXFunc::viewStatusMessage()
{
// When meta-fake key is pressed, show the key sequence so far + "M-".
if (wasMetaKey())
return keyseq.print(KeySequence::ForGui) + "M-";
// Else, when a non-complete key sequence is pressed,
// show the available options.
if (keyseq.length() > 0 && !keyseq.deleted())
return keyseq.printOptions(true);
return docstring();
}
bool LyXFunc::wasMetaKey() const
{
return (meta_fake_bit != NoModifier);
}
namespace {
} // namespace anon
} // namespace lyx } // namespace lyx

View File

@ -49,21 +49,9 @@ public:
/// LyX dispatcher, executes lyx actions. /// LyX dispatcher, executes lyx actions.
void dispatch(FuncRequest const &); void dispatch(FuncRequest const &);
///
void initKeySequences(KeyMap * kb);
/// return the status bar state string
docstring viewStatusMessage();
///
void processKeySym(KeySymbol const & key, KeyModifier state);
/// ///
FuncStatus getStatus(FuncRequest const & action) const; FuncStatus getStatus(FuncRequest const & action) const;
/// The last key was meta
bool wasMetaKey() const;
/// True if lyxfunc reports an error /// True if lyxfunc reports an error
bool errorStat() const { return errorstat; } bool errorStat() const { return errorstat; }
/// Buffer to store result messages /// Buffer to store result messages
@ -72,8 +60,6 @@ public:
void setErrorMessage(docstring const &) const; void setErrorMessage(docstring const &) const;
/// Buffer to store result messages /// Buffer to store result messages
docstring const getMessage() const { return dispatch_buffer; } docstring const getMessage() const { return dispatch_buffer; }
/// Handle a accented char key sequence
void handleKeyFunc(FuncCode action);
/// goto a bookmark /// goto a bookmark
/// openFile: whether or not open a file if the file is not opened /// openFile: whether or not open a file if the file is not opened
/// switchToBuffer: whether or not switch to buffer if the buffer is /// switchToBuffer: whether or not switch to buffer if the buffer is
@ -86,16 +72,6 @@ public:
int cursorBeforeDispatchY() const { return cursorPosBeforeDispatchY_; } int cursorBeforeDispatchY() const { return cursorPosBeforeDispatchY_; }
private: private:
/// the last character added to the key sequence, in UCS4 encoded form
char_type encoded_last_key;
///
KeySequence keyseq;
///
KeySequence cancel_meta_seq;
///
KeyModifier meta_fake_bit;
/// cursor position before dispatch started /// cursor position before dispatch started
int cursorPosBeforeDispatchX_; int cursorPosBeforeDispatchX_;
int cursorPosBeforeDispatchY_; int cursorPosBeforeDispatchY_;

View File

@ -1996,7 +1996,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
case LFUN_ACCENT_HUNGARIAN_UMLAUT: case LFUN_ACCENT_HUNGARIAN_UMLAUT:
case LFUN_ACCENT_CIRCLE: case LFUN_ACCENT_CIRCLE:
case LFUN_ACCENT_OGONEK: case LFUN_ACCENT_OGONEK:
theLyXFunc().handleKeyFunc(cmd.action); theApp()->handleKeyFunc(cmd.action);
if (!cmd.argument().empty()) if (!cmd.argument().empty())
// FIXME: Are all these characters encoded in one byte in utf8? // FIXME: Are all these characters encoded in one byte in utf8?
bv->translateAndInsert(cmd.argument()[0], this, cur); bv->translateAndInsert(cmd.argument()[0], this, cur);
@ -2741,7 +2741,6 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
case LFUN_NOACTION: case LFUN_NOACTION:
case LFUN_NOTE_NEXT: case LFUN_NOTE_NEXT:
case LFUN_REFERENCE_NEXT: case LFUN_REFERENCE_NEXT:
case LFUN_SERVER_NOTIFY:
case LFUN_SERVER_SET_XY: case LFUN_SERVER_SET_XY:
case LFUN_TEXTSTYLE_APPLY: case LFUN_TEXTSTYLE_APPLY:
case LFUN_TEXTSTYLE_UPDATE: case LFUN_TEXTSTYLE_UPDATE:

View File

@ -12,6 +12,9 @@
#define APPLICATION_H #define APPLICATION_H
#include "ColorCode.h" #include "ColorCode.h"
#include "FuncCode.h"
#include "KeyModifier.h"
#include "support/strfwd.h" #include "support/strfwd.h"
@ -24,6 +27,7 @@ namespace lyx {
class BufferView; class BufferView;
class Buffer; class Buffer;
class DispatchResult;
class docstring_list; class docstring_list;
class FuncRequest; class FuncRequest;
class FuncStatus; class FuncStatus;
@ -172,8 +176,7 @@ public:
/// ///
virtual bool getStatus(FuncRequest const & cmd, FuncStatus & flag) const = 0; virtual bool getStatus(FuncRequest const & cmd, FuncStatus & flag) const = 0;
/// dispatch command. /// dispatch command.
/// \return true if the \c FuncRequest has been dispatched. virtual void dispatch(FuncRequest const & cmd, DispatchResult & dr) = 0;
virtual bool dispatch(FuncRequest const & cmd) = 0;
/// ///
virtual void resetGui() = 0; virtual void resetGui() = 0;
@ -228,6 +231,10 @@ public:
/// \return the icon file name for the given action. /// \return the icon file name for the given action.
virtual docstring iconName(FuncRequest const & f, bool unknown) = 0; virtual docstring iconName(FuncRequest const & f, bool unknown) = 0;
/// Handle a accented char key sequence
/// FIXME: this is only needed for LFUN_ACCENT_* in Text::dispatch()
virtual void handleKeyFunc(FuncCode action) = 0;
}; };
/// Return the list of loadable formats. /// Return the list of loadable formats.

View File

@ -37,12 +37,15 @@
#include "Font.h" #include "Font.h"
#include "FuncRequest.h" #include "FuncRequest.h"
#include "FuncStatus.h" #include "FuncStatus.h"
#include "Intl.h"
#include "Language.h" #include "Language.h"
#include "LaTeXFeatures.h"
#include "Lexer.h" #include "Lexer.h"
#include "LyX.h" #include "LyX.h"
#include "LyXAction.h" #include "LyXAction.h"
#include "LyXFunc.h" #include "LyXFunc.h"
#include "LyXRC.h" #include "LyXRC.h"
#include "Server.h"
#include "Session.h" #include "Session.h"
#include "version.h" #include "version.h"
@ -59,6 +62,8 @@
#include "support/Messages.h" #include "support/Messages.h"
#include "support/os.h" #include "support/os.h"
#include "support/Package.h" #include "support/Package.h"
#include "support/Path.h"
#include "support/Systemcall.h"
#ifdef Q_WS_MACX #ifdef Q_WS_MACX
#include "support/linkback/LinkBackProxy.h" #include "support/linkback/LinkBackProxy.h"
@ -471,7 +476,7 @@ public:
QKeyEvent * ke = static_cast<QKeyEvent*>(e); QKeyEvent * ke = static_cast<QKeyEvent*>(e);
KeySymbol sym; KeySymbol sym;
setKeySymbol(&sym, ke); setKeySymbol(&sym, ke);
theLyXFunc().processKeySym(sym, q_key_state(ke->modifiers())); guiApp->processKeySym(sym, q_key_state(ke->modifiers()));
e->accept(); e->accept();
return true; return true;
} }
@ -644,12 +649,20 @@ public:
struct GuiApplication::Private struct GuiApplication::Private
{ {
Private(): language_model_(0), global_menubar_(0) Private(): language_model_(0), global_menubar_(0),
encoded_last_key(0), meta_fake_bit(NoModifier)
{ {
#ifdef Q_WS_WIN #ifdef Q_WS_WIN
/// WMF Mime handler for Windows clipboard. /// WMF Mime handler for Windows clipboard.
wmf_mime_ = new QWindowsMimeMetafile(); wmf_mime_ = new QWindowsMimeMetafile();
#endif #endif
initKeySequences(&theTopLevelKeymap());
}
void initKeySequences(KeyMap * kb)
{
keyseq = KeySequence(kb, kb);
cancel_meta_seq = KeySequence(kb, kb);
} }
/// ///
@ -680,6 +693,16 @@ struct GuiApplication::Private
/// delayed FuncRequests /// delayed FuncRequests
std::queue<FuncRequest> func_request_queue_; std::queue<FuncRequest> func_request_queue_;
/// the last character added to the key sequence, in UCS4 encoded form
char_type encoded_last_key;
///
KeySequence keyseq;
///
KeySequence cancel_meta_seq;
///
KeyModifier meta_fake_bit;
/// 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
@ -833,6 +856,13 @@ bool GuiApplication::getStatus(FuncRequest const & cmd, FuncStatus & flag) const
case LFUN_SET_COLOR: case LFUN_SET_COLOR:
case LFUN_WINDOW_NEW: case LFUN_WINDOW_NEW:
case LFUN_LYX_QUIT: case LFUN_LYX_QUIT:
case LFUN_LYXRC_APPLY:
case LFUN_COMMAND_PREFIX:
case LFUN_CANCEL:
case LFUN_META_PREFIX:
case LFUN_RECONFIGURE:
case LFUN_SERVER_GET_FILENAME:
case LFUN_SERVER_NOTIFY:
enable = true; enable = true;
break; break;
@ -847,7 +877,44 @@ bool GuiApplication::getStatus(FuncRequest const & cmd, FuncStatus & flag) const
} }
bool GuiApplication::dispatch(FuncRequest const & cmd) // This function runs "configure" and then rereads lyx.defaults to
// reconfigure the automatic settings.
static void reconfigure(LyXView * lv, string const & option)
{
// emit message signal.
if (lv)
lv->message(_("Running configure..."));
// Run configure in user lyx directory
PathChanger p(package().user_support());
string configure_command = package().configure_command();
configure_command += option;
Systemcall one;
int ret = one.startscript(Systemcall::Wait, configure_command);
p.pop();
// emit message signal.
if (lv)
lv->message(_("Reloading configuration..."));
lyxrc.read(libFileSearch(QString(), "lyxrc.defaults"));
// Re-read packages.lst
LaTeXFeatures::getAvailable();
if (ret)
Alert::information(_("System reconfiguration failed"),
_("The system reconfiguration has failed.\n"
"Default textclass is used but LyX may "
"not be able to work properly.\n"
"Please reconfigure again if needed."));
else
Alert::information(_("System reconfigured"),
_("The system has been reconfigured.\n"
"You need to restart LyX to make use of any\n"
"updated document class specifications."));
}
void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
{ {
switch (cmd.action) { switch (cmd.action) {
@ -993,13 +1060,213 @@ bool GuiApplication::dispatch(FuncRequest const & cmd)
break; break;
} }
case LFUN_LYXRC_APPLY: {
// reset active key sequences, since the bindings
// are updated (bug 6064)
d->keyseq.reset();
LyXRC const lyxrc_orig = lyxrc;
istringstream ss(to_utf8(cmd.argument()));
bool const success = lyxrc.read(ss) == 0;
if (!success) {
lyxerr << "Warning in LFUN_LYXRC_APPLY!\n"
<< "Unable to read lyxrc data"
<< endl;
break;
}
actOnUpdatedPrefs(lyxrc_orig, lyxrc);
setSpellChecker();
resetGui();
break;
}
case LFUN_COMMAND_PREFIX:
lyx::dispatch(FuncRequest(LFUN_MESSAGE, d->keyseq.printOptions(true)));
break;
case LFUN_CANCEL: {
d->keyseq.reset();
d->meta_fake_bit = NoModifier;
GuiView * gv = currentView();
if (gv && gv->currentBufferView())
// cancel any selection
lyx::dispatch(FuncRequest(LFUN_MARK_OFF));
dr.setMessage(from_ascii(N_("Cancel")));
break;
}
case LFUN_META_PREFIX:
d->meta_fake_bit = AltModifier;
dr.setMessage(d->keyseq.print(KeySequence::ForGui));
break;
// --- Menus -----------------------------------------------
case LFUN_RECONFIGURE:
// argument is any additional parameter to the configure.py command
reconfigure(currentView(), to_utf8(cmd.argument()));
break;
// --- lyxserver commands ----------------------------
case LFUN_SERVER_GET_FILENAME: {
GuiView * lv = currentView();
LASSERT(lv && lv->documentBufferView(), return);
docstring const fname = from_utf8(
lv->documentBufferView()->buffer().absFileName());
dr.setMessage(fname);
LYXERR(Debug::INFO, "FNAME[" << fname << ']');
break;
}
case LFUN_SERVER_NOTIFY: {
docstring const dispatch_buffer = d->keyseq.print(KeySequence::Portable);
dr.setMessage(dispatch_buffer);
theServer().notifyClient(to_utf8(dispatch_buffer));
break;
}
default: default:
// Notify the caller that the action has not been dispatched. // Notify the caller that the action has not been dispatched.
return false; dr.dispatched(false);
return;
} }
// The action has been dispatched. // The action has been dispatched.
return true; dr.dispatched(true);
}
docstring GuiApplication::viewStatusMessage()
{
// When meta-fake key is pressed, show the key sequence so far + "M-".
if (d->meta_fake_bit != NoModifier)
return d->keyseq.print(KeySequence::ForGui) + "M-";
// Else, when a non-complete key sequence is pressed,
// show the available options.
if (d->keyseq.length() > 0 && !d->keyseq.deleted())
return d->keyseq.printOptions(true);
return docstring();
}
void GuiApplication::handleKeyFunc(FuncCode action)
{
char_type c = d->encoded_last_key;
if (d->keyseq.length())
c = 0;
GuiView * gv = currentView();
LASSERT(gv && gv->currentBufferView(), return);
BufferView * bv = gv->currentBufferView();
bv->getIntl().getTransManager().deadkey(
c, get_accent(action).accent, bv->cursor().innerText(),
bv->cursor());
// Need to clear, in case the minibuffer calls these
// actions
d->keyseq.clear();
// copied verbatim from do_accent_char
bv->cursor().resetAnchor();
bv->processUpdateFlags(Update::FitCursor);
}
void GuiApplication::processKeySym(KeySymbol const & keysym, KeyModifier state)
{
LYXERR(Debug::KEY, "KeySym is " << keysym.getSymbolName());
LyXView * lv = theApp()->currentWindow();
// Do nothing if we have nothing (JMarc)
if (!keysym.isOK()) {
LYXERR(Debug::KEY, "Empty kbd action (probably composing)");
lv->restartCursor();
return;
}
if (keysym.isModifier()) {
LYXERR(Debug::KEY, "isModifier true");
if (lv)
lv->restartCursor();
return;
}
//Encoding const * encoding = lv->documentBufferView()->cursor().getEncoding();
//encoded_last_key = keysym.getISOEncoded(encoding ? encoding->name() : "");
// FIXME: encoded_last_key shadows the member variable of the same
// name. Is that intended?
char_type encoded_last_key = keysym.getUCSEncoded();
// Do a one-deep top-level lookup for
// cancel and meta-fake keys. RVDK_PATCH_5
d->cancel_meta_seq.reset();
FuncRequest func = d->cancel_meta_seq.addkey(keysym, state);
LYXERR(Debug::KEY, "action first set to [" << func.action << ']');
// When not cancel or meta-fake, do the normal lookup.
// Note how the meta_fake Mod1 bit is OR-ed in and reset afterwards.
// Mostly, meta_fake_bit = NoModifier. RVDK_PATCH_5.
if ((func.action != LFUN_CANCEL) && (func.action != LFUN_META_PREFIX)) {
// remove Caps Lock and Mod2 as a modifiers
func = d->keyseq.addkey(keysym, (state | d->meta_fake_bit));
LYXERR(Debug::KEY, "action now set to [" << func.action << ']');
}
// Dont remove this unless you know what you are doing.
d->meta_fake_bit = NoModifier;
// Can this happen now ?
if (func.action == LFUN_NOACTION)
func = FuncRequest(LFUN_COMMAND_PREFIX);
LYXERR(Debug::KEY, " Key [action=" << func.action << "]["
<< d->keyseq.print(KeySequence::Portable) << ']');
// already here we know if it any point in going further
// why not return already here if action == -1 and
// num_bytes == 0? (Lgb)
if (d->keyseq.length() > 1)
lv->message(d->keyseq.print(KeySequence::ForGui));
// Maybe user can only reach the key via holding down shift.
// Let's see. But only if shift is the only modifier
if (func.action == LFUN_UNKNOWN_ACTION && state == ShiftModifier) {
LYXERR(Debug::KEY, "Trying without shift");
func = d->keyseq.addkey(keysym, NoModifier);
LYXERR(Debug::KEY, "Action now " << func.action);
}
if (func.action == LFUN_UNKNOWN_ACTION) {
// Hmm, we didn't match any of the keysequences. See
// if it's normal insertable text not already covered
// by a binding
if (keysym.isText() && d->keyseq.length() == 1) {
LYXERR(Debug::KEY, "isText() is true, inserting.");
func = FuncRequest(LFUN_SELF_INSERT,
FuncRequest::KEYBOARD);
} else {
LYXERR(Debug::KEY, "Unknown, !isText() - giving up");
lv->message(_("Unknown function."));
lv->restartCursor();
return;
}
}
if (func.action == LFUN_SELF_INSERT) {
if (encoded_last_key != 0) {
docstring const arg(1, encoded_last_key);
lyx::dispatch(FuncRequest(LFUN_SELF_INSERT, arg,
FuncRequest::KEYBOARD));
LYXERR(Debug::KEY, "SelfInsert arg[`" << to_utf8(arg) << "']");
}
} else {
lyx::dispatch(func);
if (!lv)
return;
}
} }
@ -1031,7 +1298,7 @@ void GuiApplication::resetGui()
gv->resetDialogs(); gv->resetDialogs();
} }
dispatch(FuncRequest(LFUN_SCREEN_FONT_UPDATE)); lyx::dispatch(FuncRequest(LFUN_SCREEN_FONT_UPDATE));
} }

View File

@ -28,6 +28,7 @@ namespace lyx {
class BufferView; class BufferView;
class ColorCache; class ColorCache;
class KeySymbol;
namespace frontend { namespace frontend {
@ -59,7 +60,7 @@ public:
//@{ //@{
LyXView * currentWindow(); LyXView * currentWindow();
bool getStatus(FuncRequest const & cmd, FuncStatus & flag) const; bool getStatus(FuncRequest const & cmd, FuncStatus & flag) const;
bool dispatch(FuncRequest const &); void dispatch(FuncRequest const &, DispatchResult & dr);
void dispatchDelayed(FuncRequest const &); void dispatchDelayed(FuncRequest const &);
void resetGui(); void resetGui();
void restoreGuiSession(); void restoreGuiSession();
@ -77,6 +78,7 @@ public:
docstring iconName(FuncRequest const & f, bool unknown); docstring iconName(FuncRequest const & f, bool unknown);
void hideDialogs(std::string const & name, Inset * inset) const; void hideDialogs(std::string const & name, Inset * inset) const;
Buffer const * updateInset(Inset const * inset) const; Buffer const * updateInset(Inset const * inset) const;
void handleKeyFunc(FuncCode action);
//@} //@}
Toolbars const & toolbars() const; Toolbars const & toolbars() const;
@ -125,6 +127,10 @@ public:
void unregisterView(GuiView * gv); void unregisterView(GuiView * gv);
/// ///
GuiView & view(int id) const; GuiView & view(int id) const;
///
void processKeySym(KeySymbol const & key, KeyModifier state);
/// return the status bar state string
docstring viewStatusMessage();
private Q_SLOTS: private Q_SLOTS:
/// ///

View File

@ -735,7 +735,7 @@ void GuiView::updateStatusBar()
void GuiView::showMessage() void GuiView::showMessage()
{ {
QString msg = toqstr(theLyXFunc().viewStatusMessage()); QString msg = toqstr(theGuiApp()->viewStatusMessage());
if (msg.isEmpty()) { if (msg.isEmpty()) {
BufferView const * bv = currentBufferView(); BufferView const * bv = currentBufferView();
if (bv) if (bv)
@ -827,7 +827,7 @@ bool GuiView::event(QEvent * e)
// is viewed. // is viewed.
KeySymbol sym; KeySymbol sym;
setKeySymbol(&sym, ke); setKeySymbol(&sym, ke);
theLyXFunc().processKeySym(sym, q_key_state(ke->modifiers())); guiApp->processKeySym(sym, q_key_state(ke->modifiers()));
e->accept(); e->accept();
return true; return true;
} }

View File

@ -455,7 +455,7 @@ void GuiWorkArea::processKeySym(KeySymbol const & key, KeyModifier mod)
// we better stop the blinking cursor... // we better stop the blinking cursor...
// the cursor gets restarted in GuiView::restartCursor() // the cursor gets restarted in GuiView::restartCursor()
stopBlinkingCursor(); stopBlinkingCursor();
theLyXFunc().processKeySym(key, mod); guiApp->processKeySym(key, mod);
} }