Transfer LyXfunc code to GuiApplication::dispatch() and getStatus(). Now

a lot of simplification is possible. Except some instability period...


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@33389 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Abdelrazak Younes 2010-02-09 16:11:13 +00:00
parent a220c4ee4a
commit 377cdd5f6c
45 changed files with 621 additions and 827 deletions

View File

@ -96,7 +96,6 @@ src_header_files = Split('''
LyX.h
LyXAction.h
lyxfind.h
LyXFunc.h
LyXRC.h
LyXVC.h
MetricsInfo.h
@ -200,7 +199,6 @@ src_pre_files = Split('''
LyX.cpp
LyXAction.cpp
lyxfind.cpp
LyXFunc.cpp
LyXRC.cpp
LyXVC.cpp
MetricsInfo.cpp

View File

@ -42,7 +42,6 @@
#include "Lexer.h"
#include "LyXAction.h"
#include "LyX.h"
#include "LyXFunc.h"
#include "LyXRC.h"
#include "LyXVC.h"
#include "output_docbook.h"

View File

@ -34,7 +34,6 @@ class BufferSet;
class DispatchResult;
class DocIterator;
class docstring_list;
class ErrorItem;
class ErrorList;
class FuncRequest;
class FuncStatus;
@ -44,7 +43,6 @@ class InsetLabel;
class Font;
class Format;
class Lexer;
class LyXRC;
class Text;
class LyXVC;
class LaTeXFeatures;

View File

@ -39,7 +39,6 @@
#include "LyX.h"
#include "LyXAction.h"
#include "lyxfind.h"
#include "LyXFunc.h"
#include "Layout.h"
#include "LyXRC.h"
#include "MetricsInfo.h"

View File

@ -26,6 +26,7 @@
#include "FuncCode.h"
#include "FuncRequest.h"
#include "Language.h"
#include "LyX.h"
#include "LyXAction.h"
#include "LyXRC.h"
#include "Paragraph.h"
@ -1668,7 +1669,7 @@ bool Cursor::upDownInMath(bool up)
int yo = 0;
getPos(xo, yo);
xo = beforeDispatchPosX_;
// check if we had something else in mind, if not, this is the future
// target
if (x_target_ == -1)

View File

@ -29,7 +29,7 @@
#include "InsetIterator.h"
#include "InsetList.h"
#include "Language.h"
#include "LyXFunc.h"
#include "LyX.h"
#include "LyXRC.h"
#include "Text.h"
#include "Paragraph.h"

View File

@ -22,7 +22,7 @@ namespace lyx {
* through which the frontends communicate with the core.
*
* They are managed in LyXAction.cpp and handled in various
* ::dispatch() functions, starting with LyXFunc.C:dispatch(),
* ::dispatch() functions, starting with Application::dispatch(),
* BufferView::dispatch(), Cursor::dispatch() and
* Inset*::doDispatch();
*/

View File

@ -35,8 +35,8 @@
#include "Language.h"
#include "LayoutFile.h"
#include "Lexer.h"
#include "LyX.h"
#include "LyXAction.h"
#include "LyXFunc.h"
#include "LyXRC.h"
#include "ModuleList.h"
#include "Mover.h"
@ -138,8 +138,6 @@ struct LyX::Impl
delete hunspell_checker_;
}
/// our function handler
LyXFunc lyxfunc_;
///
BufferList buffer_list_;
///
@ -354,8 +352,8 @@ int LyX::exec(int & argc, char * argv[])
*/
// Note: socket callback must be registered after init(argc, argv)
// such that package().temp_dir() is properly initialized.
pimpl_->lyx_server_.reset(new Server(&pimpl_->lyxfunc_, lyxrc.lyxpipes));
pimpl_->lyx_socket_.reset(new ServerSocket(&pimpl_->lyxfunc_,
pimpl_->lyx_server_.reset(new Server(lyxrc.lyxpipes));
pimpl_->lyx_socket_.reset(new ServerSocket(
FileName(package().temp_dir().absFilename() + "/lyxsocket")));
// Start the real execution loop.
@ -517,27 +515,27 @@ void LyX::execCommands()
{
case 0:
// regular reconfigure
pimpl_->lyxfunc_.dispatch(FuncRequest(LFUN_RECONFIGURE, ""));
lyx::dispatch(FuncRequest(LFUN_RECONFIGURE, ""));
break;
case 1:
// reconfigure --without-latex-config
pimpl_->lyxfunc_.dispatch(FuncRequest(LFUN_RECONFIGURE,
lyx::dispatch(FuncRequest(LFUN_RECONFIGURE,
" --without-latex-config"));
break;
default:
pimpl_->lyxfunc_.dispatch(FuncRequest(LFUN_LYX_QUIT));
lyx::dispatch(FuncRequest(LFUN_LYX_QUIT));
return;
}
}
// create the first main window
pimpl_->lyxfunc_.dispatch(FuncRequest(LFUN_WINDOW_NEW, geometryArg));
lyx::dispatch(FuncRequest(LFUN_WINDOW_NEW, geometryArg));
if (!pimpl_->files_to_load_.empty()) {
// if some files were specified at command-line we assume that the
// user wants to edit *these* files and not to restore the session.
for (size_t i = 0; i != pimpl_->files_to_load_.size(); ++i) {
pimpl_->lyxfunc_.dispatch(
lyx::dispatch(
FuncRequest(LFUN_FILE_OPEN, pimpl_->files_to_load_[i]));
}
// clear this list to save a few bytes of RAM
@ -553,7 +551,7 @@ void LyX::execCommands()
vector<string>::const_iterator bcend = pimpl_->batch_commands.end();
for (; bcit != bcend; bcit++) {
LYXERR(Debug::INIT, "About to handle -x '" << *bcit << '\'');
pimpl_->lyxfunc_.dispatch(lyxaction.lookupFunc(*bcit));
lyx::dispatch(lyxaction.lookupFunc(*bcit));
}
}
@ -1146,22 +1144,22 @@ void LyX::easyParse(int & argc, char * argv[])
FuncStatus getStatus(FuncRequest const & action)
{
LASSERT(singleton_, /**/);
return singleton_->pimpl_->lyxfunc_.getStatus(action);
LASSERT(theApp(), /**/);
return theApp()->getStatus(action);
}
void dispatch(FuncRequest const & action)
{
LASSERT(singleton_, /**/);
singleton_->pimpl_->lyxfunc_.dispatch(action);
LASSERT(theApp(), /**/);
return theApp()->dispatch(action);
}
void dispatch(FuncRequest const & action, DispatchResult & dr)
{
LASSERT(singleton_, /**/);
singleton_->pimpl_->lyxfunc_.dispatch(action, dr);
LASSERT(theApp(), /**/);
return theApp()->dispatch(action, dr);
}
@ -1172,13 +1170,6 @@ BufferList & theBufferList()
}
LyXFunc & theLyXFunc()
{
LASSERT(singleton_, /**/);
return singleton_->pimpl_->lyxfunc_;
}
Server & theServer()
{
// FIXME: this should not be use_gui dependent

View File

@ -26,7 +26,6 @@ class ErrorItem;
class FuncRequest;
class FuncStatus;
class KeyMap;
class LyXFunc;
class Messages;
class Mover;
class Movers;
@ -124,7 +123,6 @@ private:
friend void dispatch(FuncRequest const & action);
friend void dispatch(FuncRequest const & action, DispatchResult & dr);
friend BufferList & theBufferList();
friend LyXFunc & theLyXFunc();
friend Server & theServer();
friend ServerSocket & theServerSocket();
friend Converters & theConverters();
@ -160,6 +158,12 @@ void setRcGuiLanguage();
/// Execute batch commands if available.
void execBatchCommands();
///
FuncStatus getStatus(FuncRequest const & action);
///
void dispatch(FuncRequest const & action);
} // namespace lyx
#endif // LYX_H

View File

@ -1,612 +0,0 @@
/**
* \file LyXFunc.cpp
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Alfredo Braunstein
* \author Lars Gullik Bjønnes
* \author Jean-Marc Lasgouttes
* \author Angus Leeming
* \author John Levon
* \author André Pönitz
* \author Allan Rae
* \author Dekel Tsur
* \author Martin Vermeer
* \author Jürgen Vigna
*
* Full author contact details are available in file CREDITS.
*/
#include <config.h>
#include "LyXFunc.h"
#include "LayoutFile.h"
#include "BranchList.h"
#include "buffer_funcs.h"
#include "Buffer.h"
#include "BufferList.h"
#include "BufferParams.h"
#include "BufferView.h"
#include "CmdDef.h"
#include "Color.h"
#include "Converter.h"
#include "Cursor.h"
#include "CutAndPaste.h"
#include "DispatchResult.h"
#include "Encoding.h"
#include "ErrorList.h"
#include "Format.h"
#include "FuncRequest.h"
#include "FuncStatus.h"
#include "InsetIterator.h"
#include "KeyMap.h"
#include "Language.h"
#include "Lexer.h"
#include "LyXAction.h"
#include "lyxfind.h"
#include "LyX.h"
#include "LyXRC.h"
#include "LyXVC.h"
#include "Paragraph.h"
#include "ParagraphParameters.h"
#include "ParIterator.h"
#include "Row.h"
#include "Session.h"
#include "SpellChecker.h"
#include "frontends/alert.h"
#include "frontends/Application.h"
#include "frontends/KeySymbol.h"
#include "frontends/LyXView.h"
#include "frontends/Selection.h"
#include "support/debug.h"
#include "support/environment.h"
#include "support/FileName.h"
#include "support/filetools.h"
#include "support/gettext.h"
#include "support/lassert.h"
#include "support/lstrings.h"
#include "support/Package.h"
#include "support/convert.h"
#include "support/os.h"
#include <sstream>
#include <vector>
using namespace std;
using namespace lyx::support;
namespace lyx {
using frontend::LyXView;
namespace Alert = frontend::Alert;
LyXFunc::LyXFunc()
{
}
//FIXME: bookmark handling is a frontend issue. This code should be transferred
// to GuiView and be GuiView and be window dependent.
void LyXFunc::gotoBookmark(unsigned int idx, bool openFile, bool switchToBuffer)
{
LyXView * lv = theApp()->currentWindow();
LASSERT(lv, /**/);
if (!theSession().bookmarks().isValid(idx))
return;
BookmarksSection::Bookmark const & bm = theSession().bookmarks().bookmark(idx);
LASSERT(!bm.filename.empty(), /**/);
string const file = bm.filename.absFilename();
// if the file is not opened, open it.
if (!theBufferList().exists(bm.filename)) {
if (openFile)
dispatch(FuncRequest(LFUN_FILE_OPEN, file));
else
return;
}
// open may fail, so we need to test it again
if (!theBufferList().exists(bm.filename))
return;
// bm can be changed when saving
BookmarksSection::Bookmark tmp = bm;
// Special case idx == 0 used for back-from-back jump navigation
if (idx == 0)
dispatch(FuncRequest(LFUN_BOOKMARK_SAVE, "0"));
// if the current buffer is not that one, switch to it.
if (!lv->documentBufferView()
|| lv->documentBufferView()->buffer().fileName() != tmp.filename) {
if (!switchToBuffer)
return;
dispatch(FuncRequest(LFUN_BUFFER_SWITCH, file));
}
// moveToPosition try paragraph id first and then paragraph (pit, pos).
if (!lv->documentBufferView()->moveToPosition(
tmp.bottom_pit, tmp.bottom_pos, tmp.top_id, tmp.top_pos))
return;
// bm changed
if (idx == 0)
return;
// Cursor jump succeeded!
Cursor const & cur = lv->documentBufferView()->cursor();
pit_type new_pit = cur.pit();
pos_type new_pos = cur.pos();
int new_id = cur.paragraph().id();
// if bottom_pit, bottom_pos or top_id has been changed, update bookmark
// see http://www.lyx.org/trac/ticket/3092
if (bm.bottom_pit != new_pit || bm.bottom_pos != new_pos
|| bm.top_id != new_id) {
const_cast<BookmarksSection::Bookmark &>(bm).updatePos(
new_pit, new_pos, new_id);
}
}
FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const
{
//lyxerr << "LyXFunc::getStatus: cmd: " << cmd << endl;
FuncStatus flag;
if (cmd.action == LFUN_NOACTION) {
flag.message(from_utf8(N_("Nothing to do")));
flag.setEnabled(false);
return flag;
}
if (cmd.action == LFUN_UNKNOWN_ACTION) {
flag.unknown(true);
flag.setEnabled(false);
flag.message(from_utf8(N_("Unknown action")));
return flag;
}
// I would really like to avoid having this switch and rather try to
// encode this in the function itself.
// -- And I'd rather let an inset decide which LFUNs it is willing
// to handle (Andre')
bool enable = true;
switch (cmd.action) {
// This could be used for the no-GUI version. The GUI version is handled in
// LyXView::getStatus(). See above.
/*
case LFUN_BUFFER_WRITE:
case LFUN_BUFFER_WRITE_AS: {
Buffer * b = theBufferList().getBuffer(FileName(cmd.getArg(0)));
enable = b && (b->isUnnamed() || !b->isClean());
break;
}
*/
case LFUN_BOOKMARK_GOTO: {
const unsigned int num = convert<unsigned int>(to_utf8(cmd.argument()));
enable = theSession().bookmarks().isValid(num);
break;
}
case LFUN_BOOKMARK_CLEAR:
enable = theSession().bookmarks().hasValid();
break;
// this one is difficult to get right. As a half-baked
// solution, we consider only the first action of the sequence
case LFUN_COMMAND_SEQUENCE: {
// argument contains ';'-terminated commands
string const firstcmd = token(to_utf8(cmd.argument()), ';', 0);
FuncRequest func(lyxaction.lookupFunc(firstcmd));
func.origin = cmd.origin;
flag = getStatus(func);
break;
}
// we want to check if at least one of these is enabled
case LFUN_COMMAND_ALTERNATIVES: {
// argument contains ';'-terminated commands
string arg = to_utf8(cmd.argument());
while (!arg.empty()) {
string first;
arg = split(arg, first, ';');
FuncRequest func(lyxaction.lookupFunc(first));
func.origin = cmd.origin;
flag = getStatus(func);
// if this one is enabled, the whole thing is
if (flag.enabled())
break;
}
break;
}
case LFUN_CALL: {
FuncRequest func;
string name = to_utf8(cmd.argument());
if (theTopLevelCmdDef().lock(name, func)) {
func.origin = cmd.origin;
flag = getStatus(func);
theTopLevelCmdDef().release(name);
} else {
// catch recursion or unknown command
// definition. all operations until the
// recursion or unknown command definition
// occurs are performed, so set the state to
// enabled
enable = true;
}
break;
}
case LFUN_CURSOR_FOLLOWS_SCROLLBAR_TOGGLE:
case LFUN_REPEAT:
case LFUN_PREFERENCES_SAVE:
case LFUN_BUFFER_SAVE_AS_DEFAULT:
case LFUN_DEBUG_LEVEL_SET:
// these are handled in our dispatch()
break;
default:
if (!theApp()) {
enable = false;
break;
}
if (theApp()->getStatus(cmd, flag))
break;
// Does the view know something?
LyXView * lv = theApp()->currentWindow();
if (!lv) {
enable = false;
break;
}
if (lv->getStatus(cmd, flag))
break;
BufferView * bv = lv->currentBufferView();
BufferView * doc_bv = lv->documentBufferView();
// If we do not have a BufferView, then other functions are disabled
if (!bv) {
enable = false;
break;
}
// try the BufferView
bool decided = bv->getStatus(cmd, flag);
if (!decided)
// try the Buffer
decided = bv->buffer().getStatus(cmd, flag);
if (!decided && doc_bv)
// try the Document Buffer
decided = doc_bv->buffer().getStatus(cmd, flag);
}
if (!enable)
flag.setEnabled(false);
// the default error message if we disable the command
if (!flag.enabled() && flag.message().empty())
flag.message(from_utf8(N_("Command disabled")));
return flag;
}
/// make a post-dispatch status message
static docstring makeDispatchMessage(docstring const & msg,
FuncRequest const & cmd)
{
const bool verbose = (cmd.origin == FuncRequest::MENU
|| cmd.origin == FuncRequest::TOOLBAR
|| cmd.origin == FuncRequest::COMMANDBUFFER);
if (cmd.action == LFUN_SELF_INSERT || !verbose) {
LYXERR(Debug::ACTION, "dispatch msg is " << msg);
return msg;
}
docstring dispatch_msg = msg;
if (!dispatch_msg.empty())
dispatch_msg += ' ';
docstring comname = from_utf8(lyxaction.getActionName(cmd.action));
bool argsadded = false;
if (!cmd.argument().empty()) {
if (cmd.action != LFUN_UNKNOWN_ACTION) {
comname += ' ' + cmd.argument();
argsadded = true;
}
}
docstring const shortcuts = theTopLevelKeymap().
printBindings(cmd, KeySequence::ForGui);
if (!shortcuts.empty())
comname += ": " + shortcuts;
else if (!argsadded && !cmd.argument().empty())
comname += ' ' + cmd.argument();
if (!comname.empty()) {
comname = rtrim(comname);
dispatch_msg += '(' + rtrim(comname) + ')';
}
LYXERR(Debug::ACTION, "verbose dispatch msg " << to_utf8(dispatch_msg));
return dispatch_msg;
}
void LyXFunc::dispatch(FuncRequest const & cmd)
{
LyXView * lv = theApp()->currentWindow();
if (lv && lv->currentBufferView())
lv->currentBufferView()->cursor().saveBeforeDispatchPosXY();
DispatchResult dr;
// redraw the screen at the end (first of the two drawing steps).
//This is done unless explicitly requested otherwise
dr.update(Update::FitCursor);
dispatch(cmd, dr);
if (lv && lv->currentBufferView()) {
// BufferView::update() updates the ViewMetricsInfo and
// also initializes the position cache for all insets in
// (at least partially) visible top-level paragraphs.
// We will redraw the screen only if needed.
lv->currentBufferView()->processUpdateFlags(dr.update());
// Do we have a selection?
theSelection().haveSelection(
lv->currentBufferView()->cursor().selection());
// update gui
lv->restartCursor();
}
}
void LyXFunc::dispatch(FuncRequest const & cmd, DispatchResult & dr)
{
string const argument = to_utf8(cmd.argument());
FuncCode const action = cmd.action;
LYXERR(Debug::ACTION, "\nLyXFunc::dispatch: cmd: " << cmd);
// we have not done anything wrong yet.
dr.setError(false);
LyXView * lv = theApp()->currentWindow();
FuncStatus const flag = getStatus(cmd);
if (!flag.enabled()) {
// We cannot use this function here
LYXERR(Debug::ACTION, "LyXFunc::dispatch: "
<< lyxaction.getActionName(action)
<< " [" << action << "] is disabled at this location");
if (lv)
lv->restartCursor();
dr.setMessage(flag.message());
dr.setError(true);
dr.dispatched(false);
dr.update(Update::None);
} else {
switch (action) {
case LFUN_CURSOR_FOLLOWS_SCROLLBAR_TOGGLE:
lyxrc.cursor_follows_scrollbar = !lyxrc.cursor_follows_scrollbar;
break;
case LFUN_REPEAT: {
// repeat command
string countstr;
string rest = split(argument, countstr, ' ');
istringstream is(countstr);
int count = 0;
is >> count;
//lyxerr << "repeat: count: " << count << " cmd: " << rest << endl;
for (int i = 0; i < count; ++i)
dispatch(lyxaction.lookupFunc(rest));
break;
}
case LFUN_COMMAND_SEQUENCE: {
// argument contains ';'-terminated commands
string arg = argument;
// FIXME: this LFUN should also work without any view.
Buffer * buffer = (lv && lv->documentBufferView())
? &(lv->documentBufferView()->buffer()) : 0;
if (buffer)
buffer->undo().beginUndoGroup();
while (!arg.empty()) {
string first;
arg = split(arg, first, ';');
FuncRequest func(lyxaction.lookupFunc(first));
func.origin = cmd.origin;
dispatch(func);
}
// the buffer may have been closed by one action
if (theBufferList().isLoaded(buffer))
buffer->undo().endUndoGroup();
break;
}
case LFUN_COMMAND_ALTERNATIVES: {
// argument contains ';'-terminated commands
string arg = argument;
while (!arg.empty()) {
string first;
arg = split(arg, first, ';');
FuncRequest func(lyxaction.lookupFunc(first));
func.origin = cmd.origin;
FuncStatus stat = getStatus(func);
if (stat.enabled()) {
dispatch(func);
break;
}
}
break;
}
case LFUN_CALL: {
FuncRequest func;
if (theTopLevelCmdDef().lock(argument, func)) {
func.origin = cmd.origin;
dispatch(func);
theTopLevelCmdDef().release(argument);
} else {
if (func.action == LFUN_UNKNOWN_ACTION) {
// unknown command definition
lyxerr << "Warning: unknown command definition `"
<< argument << "'"
<< endl;
} else {
// recursion detected
lyxerr << "Warning: Recursion in the command definition `"
<< argument << "' detected"
<< endl;
}
}
break;
}
case LFUN_PREFERENCES_SAVE: {
lyxrc.write(makeAbsPath("preferences",
package().user_support().absFilename()),
false);
break;
}
case LFUN_BUFFER_SAVE_AS_DEFAULT: {
string const fname =
addName(addPath(package().user_support().absFilename(), "templates/"),
"defaults.lyx");
Buffer defaults(fname);
istringstream ss(argument);
Lexer lex;
lex.setStream(ss);
int const unknown_tokens = defaults.readHeader(lex);
if (unknown_tokens != 0) {
lyxerr << "Warning in LFUN_BUFFER_SAVE_AS_DEFAULT!\n"
<< unknown_tokens << " unknown token"
<< (unknown_tokens == 1 ? "" : "s")
<< endl;
}
if (defaults.writeFile(FileName(defaults.absFileName())))
dr.setMessage(bformat(_("Document defaults saved in %1$s"),
makeDisplayPath(fname)));
else {
dr.setError(true);
dr.setMessage(from_ascii(N_("Unable to save document defaults")));
}
break;
}
case LFUN_BOOKMARK_GOTO:
// go to bookmark, open unopened file and switch to buffer if necessary
gotoBookmark(convert<unsigned int>(to_utf8(cmd.argument())), true, true);
dr.update(Update::FitCursor);
break;
case LFUN_BOOKMARK_CLEAR:
theSession().bookmarks().clear();
break;
case LFUN_DEBUG_LEVEL_SET:
lyxerr.setLevel(Debug::value(to_utf8(cmd.argument())));
break;
default:
LASSERT(theApp(), /**/);
// Let the frontend dispatch its own actions.
theApp()->dispatch(cmd, dr);
if (dr.dispatched())
// Nothing more to do.
break;
// Everything below is only for active window
if (lv == 0)
break;
// Let the current LyXView dispatch its own actions.
lv->dispatch(cmd, dr);
if (dr.dispatched())
break;
BufferView * bv = lv->currentBufferView();
LASSERT(bv, /**/);
// Let the current BufferView dispatch its own actions.
bv->dispatch(cmd, dr);
if (dr.dispatched())
break;
BufferView * doc_bv = lv->documentBufferView();
// Try with the document BufferView dispatch if any.
if (doc_bv) {
doc_bv->dispatch(cmd, dr);
if (dr.dispatched())
break;
}
// OK, so try the current Buffer itself...
bv->buffer().dispatch(cmd, dr);
if (dr.dispatched())
break;
// and with the document Buffer.
if (doc_bv) {
doc_bv->buffer().dispatch(cmd, dr);
if (dr.dispatched())
break;
}
// Let the current Cursor dispatch its own actions.
Cursor old = bv->cursor();
bv->cursor().dispatch(cmd);
// notify insets we just left
if (bv->cursor() != old) {
old.fixIfBroken();
bool badcursor = notifyCursorLeavesOrEnters(old, bv->cursor());
if (badcursor)
bv->cursor().fixIfBroken();
}
// update completion. We do it here and not in
// processKeySym to avoid another redraw just for a
// changed inline completion
if (cmd.origin == FuncRequest::KEYBOARD) {
if (cmd.action == LFUN_SELF_INSERT
|| (cmd.action == LFUN_ERT_INSERT && bv->cursor().inMathed()))
lv->updateCompletion(bv->cursor(), true, true);
else if (cmd.action == LFUN_CHAR_DELETE_BACKWARD)
lv->updateCompletion(bv->cursor(), false, true);
else
lv->updateCompletion(bv->cursor(), false, false);
}
dr = bv->cursor().result();
}
// if we executed a mutating lfun, mark the buffer as dirty
Buffer * doc_buffer = (lv && lv->documentBufferView())
? &(lv->documentBufferView()->buffer()) : 0;
if (doc_buffer && theBufferList().isLoaded(doc_buffer)
&& flag.enabled()
&& !lyxaction.funcHasFlag(action, LyXAction::NoBuffer)
&& !lyxaction.funcHasFlag(action, LyXAction::ReadOnly))
lv->currentBufferView()->buffer().markDirty();
}
if (lv) {
// Some messages may already be translated, so we cannot use _()
lv->message(makeDispatchMessage(translateIfPossible(dr.message()), cmd));
}
}
} // namespace lyx

View File

@ -1,84 +0,0 @@
// -*- C++ -*-
/**
* \file LyXFunc.h
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Lars Gullik Bjønnes
* \author Jean-Marc Lasgouttes
* \author John Levon
* \author André Pönitz
*
* Full author contact details are available in file CREDITS.
*/
#ifndef LYXFUNC_H
#define LYXFUNC_H
#include "FuncCode.h"
#include "KeySequence.h"
#include "support/docstring.h"
namespace lyx {
class Buffer;
class BufferView;
class DispatchResult;
class DocumentClass;
class FuncRequest;
class FuncStatus;
class KeySymbol;
class Text;
namespace support {
class FileName;
}
/** This class encapsulates all the LyX command operations.
This is the class of the LyX's "high level event handler".
Every user command is processed here, either invocated from
keyboard or from the GUI. All GUI objects, including buttons and
menus should use this class and never call kernel functions directly.
*/
//FIXME: this should not be a class anymore
class LyXFunc
{
public:
///
explicit LyXFunc();
/// LyX dispatcher: executes lyx actions and returns result.
void dispatch(FuncRequest const &, DispatchResult &);
/// LyX dispatcher: executes lyx actions and does necessary
/// screen updates depending on results.
void dispatch(FuncRequest const &);
///
FuncStatus getStatus(FuncRequest const & action) const;
/// goto a bookmark
/// openFile: whether or not open a file if the file is not opened
/// switchToBuffer: whether or not switch to buffer if the buffer is
/// not the current buffer
void gotoBookmark(unsigned int idx, bool openFile, bool switchToBuffer);
};
/// Implementation is in LyX.cpp
extern LyXFunc & theLyXFunc();
/// Implementation is in LyX.cpp
extern FuncStatus getStatus(FuncRequest const & action);
/// Implementation is in LyX.cpp
extern void dispatch(FuncRequest const & action);
/// Implementation is in LyX.cpp
extern void dispatch(FuncRequest const & action, DispatchResult & dr);
} // namespace lyx
#endif

View File

@ -141,7 +141,6 @@ SOURCEFILESCORE = \
LyX.cpp \
LyXAction.cpp \
lyxfind.cpp \
LyXFunc.cpp \
LyXRC.cpp \
LyXVC.cpp \
MetricsInfo.cpp \
@ -241,7 +240,6 @@ HEADERFILESCORE = \
Lexer.h \
LyXAction.h \
lyxfind.h \
LyXFunc.h \
LyX.h \
LyXRC.h \
LyXVC.h \

View File

@ -44,8 +44,8 @@
#include "DispatchResult.h"
#include "FuncRequest.h"
#include "LyX.h"
#include "LyXAction.h"
#include "LyXFunc.h"
#include "frontends/Application.h"
@ -988,8 +988,8 @@ void ServerCallback(Server * server, string const & msg)
server->callback(msg);
}
Server::Server(LyXFunc * f, string const & pipes)
: numclients_(0), func_(f), pipes_(pipes, this, &ServerCallback)
Server::Server(string const & pipes)
: numclients_(0), pipes_(pipes, this, &ServerCallback)
{}
@ -1115,7 +1115,7 @@ void Server::callback(string const & msg)
FuncRequest const fr(lyxaction.lookupFunc(cmd), arg);
DispatchResult dr;
func_->dispatch(fr, dr);
theApp()->dispatch(fr, dr);
string const rval = to_utf8(dr.message());
// all commands produce an INFO or ERROR message

View File

@ -25,7 +25,6 @@
namespace lyx {
class LyXFunc;
class Server;
@ -188,15 +187,12 @@ public:
// FIXME IN 0.13
// Hack! This should be changed in 0.13
// The lyx server should not take an argument "LyXFunc" but this is
// how it will be done for 0.12. In 0.13 we must write a non-gui
// bufferview.
// IMO lyxserver is atypical, and for the moment the only one, non-gui
// bufferview. We just have to find a way to handle situations like if
// lyxserver is using a buffer that is being edited with a bufferview.
// With a common buffer list this is not a problem, maybe. (Alejandro)
///
Server(LyXFunc * f, std::string const & pip);
Server(std::string const & pip);
///
~Server();
///
@ -219,13 +215,11 @@ private:
///
int numclients_;
///
LyXFunc * func_;
///
LyXComm pipes_;
};
/// Implementation is in LyX.cpp
extern Server & theServer();
Server & theServer();
} // namespace lyx

View File

@ -18,8 +18,8 @@
#include "DispatchResult.h"
#include "FuncRequest.h"
#include "LyX.h"
#include "LyXAction.h"
#include "LyXFunc.h"
#include "frontends/Application.h"
@ -47,9 +47,8 @@ namespace lyx {
// Address is the unix address for the socket.
// MAX_CLIENTS is the maximum number of clients
// that can connect at the same time.
ServerSocket::ServerSocket(LyXFunc * f, FileName const & addr)
: func(f),
fd_(socktools::listen(addr, 3)),
ServerSocket::ServerSocket(FileName const & addr)
: fd_(socktools::listen(addr, 3)),
address_(addr)
{
if (fd_ == -1) {
@ -143,7 +142,7 @@ void ServerSocket::dataCallback(int fd)
if (key == "LYXCMD") {
string const cmd = line.substr(pos + 1);
DispatchResult dr;
func->dispatch(lyxaction.lookupFunc(cmd), dr);
theApp()->dispatch(lyxaction.lookupFunc(cmd), dr);
string const rval = to_utf8(dr.message());
if (dr.error())
client->writeln("ERROR:" + cmd + ':' + rval);

View File

@ -26,7 +26,6 @@
namespace lyx {
class LyXDataSocket;
class LyXFunc;
/** Sockets can be in two states: listening and connected.
@ -41,7 +40,7 @@ class LyXFunc;
class ServerSocket {
public:
///
ServerSocket(LyXFunc *, support::FileName const &);
ServerSocket(support::FileName const &);
///
~ServerSocket();
/// Address of the local socket
@ -53,8 +52,6 @@ public:
private:
///
void writeln(std::string const &);
///
LyXFunc * func;
/// File descriptor for the server socket
int fd_;
/// Stores the socket filename

View File

@ -37,7 +37,7 @@
#include "Language.h"
#include "Layout.h"
#include "Lexer.h"
#include "LyXFunc.h"
#include "LyX.h"
#include "LyXRC.h"
#include "Paragraph.h"
#include "ParagraphParameters.h"

View File

@ -37,7 +37,7 @@
#include "Language.h"
#include "Layout.h"
#include "LyXAction.h"
#include "LyXFunc.h"
#include "LyX.h"
#include "Lexer.h"
#include "LyXRC.h"
#include "Paragraph.h"

View File

@ -12,7 +12,7 @@
#include "VCBackend.h"
#include "Buffer.h"
#include "LyXFunc.h"
#include "LyX.h"
#include "FuncRequest.h"
#include "frontends/alert.h"

View File

@ -173,10 +173,21 @@ public:
virtual ~Application() {}
///
virtual LyXView * currentWindow() = 0;
/// LyX dispatcher: executes lyx actions and does necessary
/// screen updates depending on results.
/// This method encapsulates all the LyX command operations.
/// This is the class of the LyX's "high level event handler".
/// Every user command is processed here, either invocated from
/// keyboard or from the GUI. All GUI objects, including buttons and
/// menus should use this class and never call kernel functions directly.
virtual void dispatch(FuncRequest const &) = 0;
/// LyX dispatcher: executes lyx actions and returns result.
virtual void dispatch(FuncRequest const &, DispatchResult & dr) = 0;
///
virtual bool getStatus(FuncRequest const & cmd, FuncStatus & flag) const = 0;
/// dispatch command.
virtual void dispatch(FuncRequest const & cmd, DispatchResult & dr) = 0;
virtual FuncStatus getStatus(FuncRequest const & cmd) const = 0;
///
virtual void resetGui() = 0;

View File

@ -15,7 +15,7 @@
#include "FuncRequest.h"
#include "FuncStatus.h"
#include "GuiView.h"
#include "LyXFunc.h"
#include "LyX.h"
#include "qt_helpers.h"
#include "support/debug.h"
@ -61,7 +61,7 @@ void Action::update()
void Action::action()
{
//LYXERR(Debug::ACTION, "calling LyXFunc::dispatch: func_: ");
//LYXERR(Debug::ACTION, "calling lyx::dispatch: func_: ");
lyx::dispatch(func_);
triggered(this);

View File

@ -20,7 +20,7 @@
#include "Cursor.h"
#include "FuncRequest.h"
#include "FuncStatus.h"
#include "LyXFunc.h"
#include "LyX.h"
#include "insets/Inset.h"

View File

@ -20,7 +20,6 @@
#include "BufferView.h"
#include "Buffer.h"
#include "LyX.h"
#include "LyXFunc.h"
#include "Text.h"
#include "lyxfind.h"

View File

@ -33,6 +33,7 @@
#include "Buffer.h"
#include "BufferList.h"
#include "BufferView.h"
#include "CmdDef.h"
#include "Color.h"
#include "Font.h"
#include "FuncRequest.h"
@ -44,14 +45,14 @@
#include "Lexer.h"
#include "LyX.h"
#include "LyXAction.h"
#include "LyXFunc.h"
#include "LyXRC.h"
#include "Paragraph.h"
#include "Server.h"
#include "Session.h"
#include "SpellChecker.h"
#include "version.h"
#include "support/lassert.h"
#include "support/convert.h"
#include "support/debug.h"
#include "support/ExceptionMessage.h"
#include "support/FileName.h"
@ -59,6 +60,7 @@
#include "support/foreach.h"
#include "support/ForkedCalls.h"
#include "support/gettext.h"
#include "support/lassert.h"
#include "support/lstrings.h"
#include "support/lyxalgo.h" // sorted
#include "support/Messages.h"
@ -830,11 +832,104 @@ LyXView * GuiApplication::currentWindow()
}
bool GuiApplication::getStatus(FuncRequest const & cmd, FuncStatus & flag) const
FuncStatus GuiApplication::getStatus(FuncRequest const & cmd) const
{
bool enable = true;
FuncStatus flag;
switch(cmd.action) {
if (cmd.action == LFUN_NOACTION) {
flag.message(from_utf8(N_("Nothing to do")));
flag.setEnabled(false);
return flag;
}
if (cmd.action == LFUN_UNKNOWN_ACTION) {
flag.unknown(true);
flag.setEnabled(false);
flag.message(from_utf8(N_("Unknown action")));
return flag;
}
// I would really like to avoid having this switch and rather try to
// encode this in the function itself.
// -- And I'd rather let an inset decide which LFUNs it is willing
// to handle (Andre')
bool enable = true;
switch (cmd.action) {
// This could be used for the no-GUI version. The GUI version is handled in
// LyXView::getStatus(). See above.
/*
case LFUN_BUFFER_WRITE:
case LFUN_BUFFER_WRITE_AS: {
Buffer * b = theBufferList().getBuffer(FileName(cmd.getArg(0)));
enable = b && (b->isUnnamed() || !b->isClean());
break;
}
*/
case LFUN_BOOKMARK_GOTO: {
const unsigned int num = convert<unsigned int>(to_utf8(cmd.argument()));
enable = theSession().bookmarks().isValid(num);
break;
}
case LFUN_BOOKMARK_CLEAR:
enable = theSession().bookmarks().hasValid();
break;
// this one is difficult to get right. As a half-baked
// solution, we consider only the first action of the sequence
case LFUN_COMMAND_SEQUENCE: {
// argument contains ';'-terminated commands
string const firstcmd = token(to_utf8(cmd.argument()), ';', 0);
FuncRequest func(lyxaction.lookupFunc(firstcmd));
func.origin = cmd.origin;
flag = getStatus(func);
break;
}
// we want to check if at least one of these is enabled
case LFUN_COMMAND_ALTERNATIVES: {
// argument contains ';'-terminated commands
string arg = to_utf8(cmd.argument());
while (!arg.empty()) {
string first;
arg = split(arg, first, ';');
FuncRequest func(lyxaction.lookupFunc(first));
func.origin = cmd.origin;
flag = getStatus(func);
// if this one is enabled, the whole thing is
if (flag.enabled())
break;
}
break;
}
case LFUN_CALL: {
FuncRequest func;
string name = to_utf8(cmd.argument());
if (theTopLevelCmdDef().lock(name, func)) {
func.origin = cmd.origin;
flag = getStatus(func);
theTopLevelCmdDef().release(name);
} else {
// catch recursion or unknown command
// definition. all operations until the
// recursion or unknown command definition
// occurs are performed, so set the state to
// enabled
enable = true;
}
break;
}
case LFUN_CURSOR_FOLLOWS_SCROLLBAR_TOGGLE:
case LFUN_REPEAT:
case LFUN_PREFERENCES_SAVE:
case LFUN_BUFFER_SAVE_AS_DEFAULT:
case LFUN_DEBUG_LEVEL_SET:
// these are handled in our dispatch()
break;
case LFUN_WINDOW_CLOSE:
enable = d->views_.size() > 0;
@ -859,15 +954,190 @@ bool GuiApplication::getStatus(FuncRequest const & cmd, FuncStatus & flag) const
break;
default:
return false;
// Does the view know something?
if (!current_view_) {
enable = false;
break;
}
if (current_view_->getStatus(cmd, flag))
break;
// In LyX/Mac, when a dialog is open, the menus of the
// application can still be accessed without giving focus to
// the main window. In this case, we want to disable the menu
// entries that are buffer or view-related.
//FIXME: Abdel (09/02/10) This has very bad effect on Linux, don't know why...
/*
if (cmd.origin == FuncRequest::MENU && !current_view_->hasFocus()) {
enable = false;
break;
}
*/
BufferView * bv = current_view_->currentBufferView();
BufferView * doc_bv = current_view_->documentBufferView();
// If we do not have a BufferView, then other functions are disabled
if (!bv) {
enable = false;
break;
}
// try the BufferView
bool decided = bv->getStatus(cmd, flag);
if (!decided)
// try the Buffer
decided = bv->buffer().getStatus(cmd, flag);
if (!decided && doc_bv)
// try the Document Buffer
decided = doc_bv->buffer().getStatus(cmd, flag);
}
if (!enable)
flag.setEnabled(false);
return true;
// the default error message if we disable the command
if (!flag.enabled() && flag.message().empty())
flag.message(from_utf8(N_("Command disabled")));
return flag;
}
/// make a post-dispatch status message
static docstring makeDispatchMessage(docstring const & msg,
FuncRequest const & cmd)
{
const bool verbose = (cmd.origin == FuncRequest::MENU
|| cmd.origin == FuncRequest::TOOLBAR
|| cmd.origin == FuncRequest::COMMANDBUFFER);
if (cmd.action == LFUN_SELF_INSERT || !verbose) {
LYXERR(Debug::ACTION, "dispatch msg is " << msg);
return msg;
}
docstring dispatch_msg = msg;
if (!dispatch_msg.empty())
dispatch_msg += ' ';
docstring comname = from_utf8(lyxaction.getActionName(cmd.action));
bool argsadded = false;
if (!cmd.argument().empty()) {
if (cmd.action != LFUN_UNKNOWN_ACTION) {
comname += ' ' + cmd.argument();
argsadded = true;
}
}
docstring const shortcuts = theTopLevelKeymap().
printBindings(cmd, KeySequence::ForGui);
if (!shortcuts.empty())
comname += ": " + shortcuts;
else if (!argsadded && !cmd.argument().empty())
comname += ' ' + cmd.argument();
if (!comname.empty()) {
comname = rtrim(comname);
dispatch_msg += '(' + rtrim(comname) + ')';
}
LYXERR(Debug::ACTION, "verbose dispatch msg " << to_utf8(dispatch_msg));
return dispatch_msg;
}
void GuiApplication::dispatch(FuncRequest const & cmd)
{
if (current_view_ && current_view_->currentBufferView())
current_view_->currentBufferView()->cursor().saveBeforeDispatchPosXY();
DispatchResult dr;
// redraw the screen at the end (first of the two drawing steps).
//This is done unless explicitly requested otherwise
dr.update(Update::FitCursor);
dispatch(cmd, dr);
if (!current_view_)
return;
BufferView * bv = current_view_->currentBufferView();
if (bv) {
// BufferView::update() updates the ViewMetricsInfo and
// also initializes the position cache for all insets in
// (at least partially) visible top-level paragraphs.
// We will redraw the screen only if needed.
bv->processUpdateFlags(dr.update());
// Do we have a selection?
theSelection().haveSelection(bv->cursor().selection());
// update gui
current_view_->restartCursor();
}
// Some messages may already be translated, so we cannot use _()
current_view_->message(makeDispatchMessage(
translateIfPossible(dr.message()), cmd));
}
void GuiApplication::gotoBookmark(unsigned int idx, bool openFile, bool switchToBuffer)
{
LyXView * lv = current_view_;
LASSERT(lv, /**/);
if (!theSession().bookmarks().isValid(idx))
return;
BookmarksSection::Bookmark const & bm = theSession().bookmarks().bookmark(idx);
LASSERT(!bm.filename.empty(), /**/);
string const file = bm.filename.absFilename();
// if the file is not opened, open it.
if (!theBufferList().exists(bm.filename)) {
if (openFile)
dispatch(FuncRequest(LFUN_FILE_OPEN, file));
else
return;
}
// open may fail, so we need to test it again
if (!theBufferList().exists(bm.filename))
return;
// bm can be changed when saving
BookmarksSection::Bookmark tmp = bm;
// Special case idx == 0 used for back-from-back jump navigation
if (idx == 0)
dispatch(FuncRequest(LFUN_BOOKMARK_SAVE, "0"));
// if the current buffer is not that one, switch to it.
if (!lv->documentBufferView()
|| lv->documentBufferView()->buffer().fileName() != tmp.filename) {
if (!switchToBuffer)
return;
dispatch(FuncRequest(LFUN_BUFFER_SWITCH, file));
}
// moveToPosition try paragraph id first and then paragraph (pit, pos).
if (!lv->documentBufferView()->moveToPosition(
tmp.bottom_pit, tmp.bottom_pos, tmp.top_id, tmp.top_pos))
return;
// bm changed
if (idx == 0)
return;
// Cursor jump succeeded!
Cursor const & cur = lv->documentBufferView()->cursor();
pit_type new_pit = cur.pit();
pos_type new_pos = cur.pos();
int new_id = cur.paragraph().id();
// if bottom_pit, bottom_pos or top_id has been changed, update bookmark
// see http://www.lyx.org/trac/ticket/3092
if (bm.bottom_pit != new_pit || bm.bottom_pos != new_pos
|| bm.top_id != new_id) {
const_cast<BookmarksSection::Bookmark &>(bm).updatePos(
new_pit, new_pos, new_id);
}
}
// This function runs "configure" and then rereads lyx.defaults to
// reconfigure the automatic settings.
@ -906,8 +1176,35 @@ static void reconfigure(GuiView * lv, string const & option)
}
void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
{
string const argument = to_utf8(cmd.argument());
FuncCode const action = cmd.action;
LYXERR(Debug::ACTION, "cmd: " << cmd);
// we have not done anything wrong yet.
dr.setError(false);
FuncStatus const flag = getStatus(cmd);
if (!flag.enabled()) {
// We cannot use this function here
LYXERR(Debug::ACTION, "action "
<< lyxaction.getActionName(action)
<< " [" << action << "] is disabled at this location");
if (current_view_)
current_view_->restartCursor();
dr.setMessage(flag.message());
dr.setError(true);
dr.dispatched(false);
dr.update(Update::None);
return;
};
// Assumes that the action will be dispatched.
dr.dispatched(true);
switch (cmd.action) {
case LFUN_WINDOW_NEW:
@ -917,7 +1214,7 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
case LFUN_WINDOW_CLOSE:
// update bookmark pit of the current buffer before window close
for (size_t i = 0; i < theSession().bookmarks().size(); ++i)
theLyXFunc().gotoBookmark(i+1, false, false);
gotoBookmark(i+1, false, false);
// clear the last opened list, because
// maybe this will end the session
theSession().lastOpened().clear();
@ -934,22 +1231,22 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
break;
case LFUN_SCREEN_FONT_UPDATE: {
// handle the screen font changes.
d->font_loader_.update();
// Backup current_view_
GuiView * view = current_view_;
// Set current_view_ to zero to forbid GuiWorkArea::redraw()
// to skip the refresh.
current_view_ = 0;
theBufferList().changed(false);
// Restore current_view_
current_view_ = view;
break;
}
// handle the screen font changes.
d->font_loader_.update();
// Backup current_view_
GuiView * view = current_view_;
// Set current_view_ to zero to forbid GuiWorkArea::redraw()
// to skip the refresh.
current_view_ = 0;
theBufferList().changed(false);
// Restore current_view_
current_view_ = view;
break;
}
case LFUN_BUFFER_NEW:
if (d->views_.empty()
|| (!lyxrc.open_buffers_in_tabs && current_view_->documentBufferView() != 0)) {
|| (!lyxrc.open_buffers_in_tabs && current_view_->documentBufferView() != 0)) {
createView(QString(), false); // keep hidden
current_view_->newDocument(to_utf8(cmd.argument()), false);
current_view_->show();
@ -961,7 +1258,7 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
case LFUN_BUFFER_NEW_TEMPLATE:
if (d->views_.empty()
|| (!lyxrc.open_buffers_in_tabs && current_view_->documentBufferView() != 0)) {
|| (!lyxrc.open_buffers_in_tabs && current_view_->documentBufferView() != 0)) {
createView();
current_view_->newDocument(to_utf8(cmd.argument()), true);
if (!current_view_->documentBufferView())
@ -974,7 +1271,7 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
case LFUN_FILE_OPEN:
// FIXME: create a new method shared with LFUN_HELP_OPEN.
if (d->views_.empty()
|| (!lyxrc.open_buffers_in_tabs && current_view_->documentBufferView() != 0)) {
|| (!lyxrc.open_buffers_in_tabs && current_view_->documentBufferView() != 0)) {
string const fname = to_utf8(cmd.argument());
// We want the ui session to be saved per document and not per
// window number. The filename crc is a good enough identifier.
@ -998,16 +1295,16 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
break;
}
FileName fname = i18nLibFileSearch("doc", arg, "lyx");
if (fname.empty())
if (fname.empty())
fname = i18nLibFileSearch("examples", arg, "lyx");
if (fname.empty()) {
lyxerr << "LyX: unable to find documentation file `"
<< arg << "'. Bad installation?" << endl;
<< arg << "'. Bad installation?" << endl;
break;
}
current_view_->message(bformat(_("Opening help file %1$s..."),
makeDisplayPath(fname.absFilename())));
makeDisplayPath(fname.absFilename())));
Buffer * buf = current_view_->loadDocument(fname, false);
if (buf) {
current_view_->setBuffer(buf);
@ -1023,13 +1320,13 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
string const x11_name = split(to_utf8(cmd.argument()), lyx_name, ' ');
if (lyx_name.empty() || x11_name.empty()) {
current_view_->message(
_("Syntax: set-color <lyx_name> <x11_name>"));
_("Syntax: set-color <lyx_name> <x11_name>"));
break;
}
string const graphicsbg = lcolor.getLyXName(Color_graphicsbg);
bool const graphicsbg_changed = lyx_name == graphicsbg
&& x11_name != graphicsbg;
&& x11_name != graphicsbg;
if (graphicsbg_changed) {
// FIXME: The graphics cache no longer has a changeDisplay method.
#if 0
@ -1040,9 +1337,9 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
if (!lcolor.setColor(lyx_name, x11_name)) {
current_view_->message(
bformat(_("Set-color \"%1$s\" failed "
"- color is undefined or "
"may not be redefined"),
from_utf8(lyx_name)));
"- color is undefined or "
"may not be redefined"),
from_utf8(lyx_name)));
break;
}
// Make sure we don't keep old colors in cache.
@ -1061,8 +1358,8 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
if (!success) {
lyxerr << "Warning in LFUN_LYXRC_APPLY!\n"
<< "Unable to read lyxrc data"
<< endl;
<< "Unable to read lyxrc data"
<< endl;
break;
}
@ -1074,7 +1371,7 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
}
case LFUN_COMMAND_PREFIX:
lyx::dispatch(FuncRequest(LFUN_MESSAGE, d->keyseq.printOptions(true)));
dispatch(FuncRequest(LFUN_MESSAGE, d->keyseq.printOptions(true)));
break;
case LFUN_CANCEL: {
@ -1103,7 +1400,7 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
GuiView * lv = currentView();
LASSERT(lv && lv->documentBufferView(), return);
docstring const fname = from_utf8(
lv->documentBufferView()->buffer().absFileName());
lv->documentBufferView()->buffer().absFileName());
dr.setMessage(fname);
LYXERR(Debug::INFO, "FNAME[" << fname << ']');
break;
@ -1114,14 +1411,214 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
theServer().notifyClient(to_utf8(dispatch_buffer));
break;
}
case LFUN_CURSOR_FOLLOWS_SCROLLBAR_TOGGLE:
lyxrc.cursor_follows_scrollbar = !lyxrc.cursor_follows_scrollbar;
break;
case LFUN_REPEAT: {
// repeat command
string countstr;
string rest = split(argument, countstr, ' ');
istringstream is(countstr);
int count = 0;
is >> count;
//lyxerr << "repeat: count: " << count << " cmd: " << rest << endl;
for (int i = 0; i < count; ++i)
dispatch(lyxaction.lookupFunc(rest));
break;
}
case LFUN_COMMAND_SEQUENCE: {
// argument contains ';'-terminated commands
string arg = argument;
// FIXME: this LFUN should also work without any view.
Buffer * buffer = (current_view_ && current_view_->documentBufferView())
? &(current_view_->documentBufferView()->buffer()) : 0;
if (buffer)
buffer->undo().beginUndoGroup();
while (!arg.empty()) {
string first;
arg = split(arg, first, ';');
FuncRequest func(lyxaction.lookupFunc(first));
func.origin = cmd.origin;
dispatch(func);
}
// the buffer may have been closed by one action
if (theBufferList().isLoaded(buffer))
buffer->undo().endUndoGroup();
break;
}
case LFUN_COMMAND_ALTERNATIVES: {
// argument contains ';'-terminated commands
string arg = argument;
while (!arg.empty()) {
string first;
arg = split(arg, first, ';');
FuncRequest func(lyxaction.lookupFunc(first));
func.origin = cmd.origin;
FuncStatus stat = getStatus(func);
if (stat.enabled()) {
dispatch(func);
break;
}
}
break;
}
case LFUN_CALL: {
FuncRequest func;
if (theTopLevelCmdDef().lock(argument, func)) {
func.origin = cmd.origin;
dispatch(func);
theTopLevelCmdDef().release(argument);
} else {
if (func.action == LFUN_UNKNOWN_ACTION) {
// unknown command definition
lyxerr << "Warning: unknown command definition `"
<< argument << "'"
<< endl;
} else {
// recursion detected
lyxerr << "Warning: Recursion in the command definition `"
<< argument << "' detected"
<< endl;
}
}
break;
}
case LFUN_PREFERENCES_SAVE:
lyxrc.write(support::makeAbsPath("preferences",
package().user_support().absFilename()), false);
break;
case LFUN_BUFFER_SAVE_AS_DEFAULT: {
string const fname = addName(addPath(package().user_support().absFilename(),
"templates/"), "defaults.lyx");
Buffer defaults(fname);
istringstream ss(argument);
Lexer lex;
lex.setStream(ss);
int const unknown_tokens = defaults.readHeader(lex);
if (unknown_tokens != 0) {
lyxerr << "Warning in LFUN_BUFFER_SAVE_AS_DEFAULT!\n"
<< unknown_tokens << " unknown token"
<< (unknown_tokens == 1 ? "" : "s")
<< endl;
}
if (defaults.writeFile(FileName(defaults.absFileName())))
dr.setMessage(bformat(_("Document defaults saved in %1$s"),
makeDisplayPath(fname)));
else {
dr.setError(true);
dr.setMessage(from_ascii(N_("Unable to save document defaults")));
}
break;
}
case LFUN_BOOKMARK_GOTO:
// go to bookmark, open unopened file and switch to buffer if necessary
gotoBookmark(convert<unsigned int>(to_utf8(cmd.argument())), true, true);
dr.update(Update::FitCursor);
break;
case LFUN_BOOKMARK_CLEAR:
theSession().bookmarks().clear();
break;
case LFUN_DEBUG_LEVEL_SET:
lyxerr.setLevel(Debug::value(to_utf8(cmd.argument())));
break;
default:
// Notify the caller that the action has not been dispatched.
dr.dispatched(false);
return;
break;
}
// The action has been dispatched.
dr.dispatched(true);
// The action has been dispatched in this method, nothing more to do.
if (dr.dispatched())
return;
GuiView * lv = current_view_;
// Everything below is only for active window
if (lv == 0)
return;
// Let the current LyXView dispatch its own actions.
lv->dispatch(cmd, dr);
if (dr.dispatched() && lv )
return;
BufferView * bv = lv->currentBufferView();
LASSERT(bv, /**/);
// Let the current BufferView dispatch its own actions.
bv->dispatch(cmd, dr);
if (dr.dispatched())
return;
BufferView * doc_bv = lv->documentBufferView();
// Try with the document BufferView dispatch if any.
if (doc_bv) {
doc_bv->dispatch(cmd, dr);
if (dr.dispatched())
return;
}
// OK, so try the current Buffer itself...
bv->buffer().dispatch(cmd, dr);
if (dr.dispatched())
return;
// and with the document Buffer.
if (doc_bv) {
doc_bv->buffer().dispatch(cmd, dr);
if (dr.dispatched())
return;
}
// Let the current Cursor dispatch its own actions.
Cursor old = bv->cursor();
bv->cursor().dispatch(cmd);
// notify insets we just left
if (bv->cursor() != old) {
old.fixIfBroken();
bool badcursor = notifyCursorLeavesOrEnters(old, bv->cursor());
if (badcursor)
bv->cursor().fixIfBroken();
}
// update completion. We do it here and not in
// processKeySym to avoid another redraw just for a
// changed inline completion
if (cmd.origin == FuncRequest::KEYBOARD) {
if (cmd.action == LFUN_SELF_INSERT
|| (cmd.action == LFUN_ERT_INSERT && bv->cursor().inMathed()))
lv->updateCompletion(bv->cursor(), true, true);
else if (cmd.action == LFUN_CHAR_DELETE_BACKWARD)
lv->updateCompletion(bv->cursor(), false, true);
else
lv->updateCompletion(bv->cursor(), false, false);
}
dr = bv->cursor().result();
// if we executed a mutating lfun, mark the buffer as dirty
Buffer * doc_buffer = (lv && lv->documentBufferView())
? &(lv->documentBufferView()->buffer()) : 0;
if (doc_buffer && theBufferList().isLoaded(doc_buffer)
&& flag.enabled()
&& !lyxaction.funcHasFlag(action, LyXAction::NoBuffer)
&& !lyxaction.funcHasFlag(action, LyXAction::ReadOnly))
lv->currentBufferView()->buffer().markDirty();
}

View File

@ -58,9 +58,10 @@ public:
/// \name Methods inherited from Application class
//@{
LyXView * currentWindow();
bool getStatus(FuncRequest const & cmd, FuncStatus & flag) const;
void dispatch(FuncRequest const &);
void dispatch(FuncRequest const &, DispatchResult & dr);
FuncStatus getStatus(FuncRequest const & cmd) const;
LyXView * currentWindow();
void dispatchDelayed(FuncRequest const &);
void resetGui();
void restoreGuiSession();
@ -133,6 +134,12 @@ public:
/// return the status bar state string
docstring viewStatusMessage();
/// goto a bookmark
/// openFile: whether or not open a file if the file is not opened
/// switchToBuffer: whether or not switch to buffer if the buffer is
/// not the current buffer
void gotoBookmark(unsigned int idx, bool openFile, bool switchToBuffer);
private Q_SLOTS:
///
void execBatchCommands();
@ -157,6 +164,7 @@ private:
/// This LyXView is the one receiving Clipboard and Selection
/// events
GuiView * current_view_;
///
struct Private;
Private * const d;

View File

@ -21,7 +21,7 @@
#include "BufferView.h"
#include "Cursor.h"
#include "LyXFunc.h"
#include "LyX.h"
#include "LyXAction.h"
#include "FuncRequest.h"
#include "Session.h"

View File

@ -20,7 +20,7 @@
#include "FuncRequest.h"
#include "GuiWorkArea.h"
#include "GuiView.h"
#include "LyXFunc.h"
#include "LyX.h"
#include "LyXRC.h"
#include "Paragraph.h"
#include "version.h"

View File

@ -25,7 +25,7 @@
#include "Cursor.h"
#include "FuncRequest.h"
#include "FuncStatus.h"
#include "LyXFunc.h"
#include "LyX.h"
#include "insets/InsetTabular.h"

View File

@ -30,7 +30,7 @@
#include "FuncRequest.h"
#include "FuncStatus.h"
#include "KeyMap.h"
#include "LyXFunc.h"
#include "LyX.h"
#include "LyXRC.h"
#include "support/debug.h"

View File

@ -51,7 +51,6 @@
#include "Layout.h"
#include "Lexer.h"
#include "LyXAction.h"
#include "LyXFunc.h"
#include "LyX.h"
#include "LyXRC.h"
#include "LyXVC.h"
@ -602,7 +601,7 @@ void GuiView::focusInEvent(QFocusEvent * e)
{
LYXERR(Debug::DEBUG, "GuiView::focusInEvent()" << this);
QMainWindow::focusInEvent(e);
// Make sure LyXFunc points to the correct view.
// Make sure guiApp points to the correct view.
guiApp->setCurrentView(this);
if (currentMainWorkArea())
currentMainWorkArea()->setFocus();
@ -2262,7 +2261,7 @@ bool GuiView::closeBuffer(Buffer & buf)
//FIXME: we should update only the bookmarks related to this buffer!
LYXERR(Debug::DEBUG, "GuiView::closeBuffer()");
for (size_t i = 0; i < theSession().bookmarks().size(); ++i)
theLyXFunc().gotoBookmark(i+1, false, false);
guiApp->gotoBookmark(i+1, false, false);
if (saveBufferIfNeeded(buf, false)) {
theBufferList().release(&buf);

View File

@ -32,7 +32,7 @@
#include "GuiView.h"
#include "KeySymbol.h"
#include "Language.h"
#include "LyXFunc.h"
#include "LyX.h"
#include "LyXRC.h"
#include "LyXVC.h"
#include "MetricsInfo.h"

View File

@ -18,7 +18,7 @@
#include "FuncStatus.h"
#include "FuncRequest.h"
#include "LyXFunc.h"
#include "LyX.h"
#include <QMouseEvent>
#include <QPainter>

View File

@ -26,7 +26,7 @@
#include "Cursor.h"
#include "FuncRequest.h"
#include "FuncStatus.h"
#include "LyXFunc.h"
#include "LyX.h"
#include "LyXRC.h"
#include "Paragraph.h"
#include "TextClass.h"

View File

@ -41,8 +41,7 @@
#include "Language.h"
#include "Lexer.h"
#include "LyXAction.h"
#include "LyX.h" // for lastfiles
#include "LyXFunc.h"
#include "LyX.h"
#include "LyXRC.h"
#include "Paragraph.h"
#include "ParIterator.h"

View File

@ -18,7 +18,7 @@
#include "Cursor.h"
#include "DocIterator.h"
#include "FuncRequest.h"
#include "LyXFunc.h"
#include "LyX.h"
#include "TocBackend.h"
#include "support/debug.h"

View File

@ -23,7 +23,7 @@
#include "CutAndPaste.h"
#include "FuncRequest.h"
#include "FuncStatus.h"
#include "LyXFunc.h"
#include "LyX.h"
#include "Menus.h"
#include "TocBackend.h"

View File

@ -330,7 +330,7 @@ bool Inset::getStatus(Cursor &, FuncRequest const & cmd,
// be applied. This is either changed to LFUN_INSET_MODIFY (if the
// dialog belongs to us) or LFUN_INSET_INSERT (if the dialog does
// not belong to us, i. e. the dialog was open, and the user moved
// the cursor in our inset) in LyXFunc::getStatus().
// the cursor in our inset) in lyx::getStatus().
// Dialogs::checkStatus() ensures that the dialog is deactivated if
// LFUN_INSET_APPLY is disabled.

View File

@ -29,7 +29,6 @@
#include "LayoutFile.h"
#include "LayoutModuleList.h"
#include "LyX.h"
#include "LyXFunc.h"
#include "LyXRC.h"
#include "Lexer.h"
#include "MetricsInfo.h"

View File

@ -24,7 +24,7 @@
#include "FuncStatus.h"
#include "InsetIterator.h"
#include "Language.h"
#include "LyXFunc.h"
#include "LyX.h"
#include "output_xhtml.h"
#include "ParIterator.h"
#include "sgml.h"

View File

@ -17,7 +17,7 @@
#include "FuncRequest.h"
#include "InsetLabel.h"
#include "LaTeXFeatures.h"
#include "LyXFunc.h"
#include "LyX.h"
#include "OutputParams.h"
#include "output_xhtml.h"
#include "ParIterator.h"

View File

@ -34,7 +34,7 @@
#include "Language.h"
#include "LaTeXFeatures.h"
#include "Lexer.h"
#include "LyXFunc.h"
#include "LyX.h"
#include "LyXRC.h"
#include "MetricsInfo.h"
#include "OutputParams.h"

View File

@ -25,7 +25,7 @@
#include "Cursor.h"
#include "CutAndPaste.h"
#include "FuncRequest.h"
#include "LyXFunc.h"
#include "LyX.h"
#include "output_latex.h"
#include "OutputParams.h"
#include "Paragraph.h"

View File

@ -48,7 +48,7 @@
#include "Encoding.h"
#include "FuncRequest.h"
#include "FuncStatus.h"
#include "LyXFunc.h"
#include "LyX.h"
#include "LyXRC.h"
#include "OutputParams.h"
#include "Text.h"

View File

@ -18,7 +18,7 @@
#include "FuncRequest.h"
#include "FuncStatus.h"
#include "LaTeXFeatures.h"
#include "LyXFunc.h"
#include "LyX.h"
#include "MathData.h"
#include "MathFactory.h"
#include "MathSupport.h"

View File

@ -28,7 +28,7 @@
#include "FuncStatus.h"
#include "FuncRequest.h"
#include "LaTeXFeatures.h"
#include "LyXFunc.h"
#include "LyX.h"
#include "LyXRC.h"
#include "Undo.h"