#include "FloatList.h"
#include "FuncStatus.h"
#include "buffer.h"
+#include "buffer_funcs.h"
#include "bufferparams.h"
#include "BufferView.h"
#include "cursor.h"
#include "gettext.h"
#include "intl.h"
#include "language.h"
+#include "LyXAction.h"
#include "lyxfunc.h"
#include "lyxlex.h"
#include "lyxrc.h"
#include "mathed/math_hullinset.h"
#include "mathed/math_macrotemplate.h"
+#include <boost/current_function.hpp>
+
#include <clocale>
#include <sstream>
using lyx::support::token;
using std::endl;
-using std::find;
using std::string;
using std::istringstream;
-using std::vector;
extern string current_layout;
}
-bool LyXText::gotoNextInset(LCursor & cur,
- vector<InsetBase_code> const & codes, string const & contents)
-{
- BOOST_ASSERT(this == cur.text());
- pit_type end = paragraphs().size();
- pit_type pit = cur.pit();
- pos_type pos = cur.pos();
-
- InsetBase * inset;
- do {
- if (pos + 1 < pars_[pit].size()) {
- ++pos;
- } else {
- ++pit;
- pos = 0;
- }
-
- } while (pit != end &&
- !(pars_[pit].isInset(pos) &&
- (inset = pars_[pit].getInset(pos)) != 0 &&
- find(codes.begin(), codes.end(), inset->lyxCode()) != codes.end() &&
- (contents.empty() ||
- static_cast<InsetCommand *>(pars_[pit].getInset(pos))->getContents()
- == contents)));
-
- if (pit == end)
- return false;
-
- setCursor(cur, pit, pos, false);
- return true;
-}
-
-
-void LyXText::gotoInset(LCursor & cur,
- vector<InsetBase_code> const & codes, bool same_content)
-{
- cur.clearSelection();
-
- string contents;
- if (same_content
- && cur.pos() < cur.lastpos()
- && cur.paragraph().isInset(cur.pos())) {
- InsetBase const * inset = cur.paragraph().getInset(cur.pos());
- if (find(codes.begin(), codes.end(), inset->lyxCode())
- != codes.end())
- contents = static_cast<InsetCommand const *>(inset)->getContents();
- }
-
- if (!gotoNextInset(cur, codes, contents)) {
- if (cur.pos() || cur.pit() != 0) {
- CursorSlice tmp = cur.top();
- cur.pit() = 0;
- cur.pos() = 0;
- if (!gotoNextInset(cur, codes, contents)) {
- cur.top() = tmp;
- cur.message(_("No more insets"));
- }
- } else {
- cur.message(_("No more insets"));
- }
- }
- cur.resetAnchor();
-}
-
-
-void LyXText::gotoInset(LCursor & cur, InsetBase_code code, bool same_content)
-{
- gotoInset(cur, vector<InsetBase_code>(1, code), same_content);
-}
-
-
-void LyXText::cursorPrevious(LCursor & cur)
+bool LyXText::cursorPrevious(LCursor & cur)
{
pos_type cpos = cur.pos();
lyx::pit_type cpar = cur.pit();
int x = cur.x_target();
setCursorFromCoordinates(cur, x, 0);
- cursorUp(cur);
+ bool updated = cursorUp(cur);
if (cpar == cur.pit() && cpos == cur.pos()) {
// we have a row which is taller than the workarea. The
// simplest solution is to move to the previous row instead.
- cursorUp(cur);
+ updated |= cursorUp(cur);
}
cur.bv().updateScrollbar();
finishUndo();
+ return updated;
}
-void LyXText::cursorNext(LCursor & cur)
+bool LyXText::cursorNext(LCursor & cur)
{
pos_type cpos = cur.pos();
lyx::pit_type cpar = cur.pit();
int x = cur.x_target();
setCursorFromCoordinates(cur, x, cur.bv().workHeight() - 1);
- cursorDown(cur);
+ bool updated = cursorDown(cur);
if (cpar == cur.pit() && cpos == cur.pos()) {
// we have a row which is taller than the workarea. The
// simplest solution is to move to the next row instead.
- cursorDown(cur);
+ updated |= cursorDown(cur);
}
cur.bv().updateScrollbar();
finishUndo();
+ return updated;
}
void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
{
lyxerr[Debug::ACTION] << "LyXText::dispatch: cmd: " << cmd << endl;
- //lyxerr << "*** LyXText::dispatch: cmd: " << cmd << endl;
+ lyxerr << "*** LyXText::dispatch: cmd: " << cmd << endl;
BOOST_ASSERT(cur.text() == this);
BufferView * bv = &cur.bv();
- CursorSlice sl = cur.top();
+ CursorSlice oldTopSlice = cur.top();
bool sel = cur.selection();
- bool moving = false;
+ bool needsUpdate = !lyxaction.funcHasFlag(cmd.action, LyXAction::NoUpdate);
switch (cmd.action) {
Paragraph & par = cur.paragraph();
bool start = !par.params().startOfAppendix();
+#ifdef WITH_WARNINGS
+#warning The code below only makes sense at top level.
+// Should LFUN_APPENDIX be restricted to top-level paragraphs?
+#endif
// ensure that we have only one start_of_appendix in this document
for (pit_type tmp = 0, end = pars_.size(); tmp != end; ++tmp) {
if (pars_[tmp].params().startOfAppendix()) {
par.params().startOfAppendix(start);
// we can set the refreshing parameters now
- updateCounters();
+ updateCounters(cur.buffer());
break;
}
break;
case LFUN_WORDRIGHT:
- moving = true;
if (!cur.mark())
cur.clearSelection();
if (isRTL(cur.paragraph()))
- cursorLeftOneWord(cur);
+ needsUpdate = cursorLeftOneWord(cur);
else
- cursorRightOneWord(cur);
+ needsUpdate = cursorRightOneWord(cur);
finishChange(cur, false);
break;
case LFUN_WORDLEFT:
- moving = true;
if (!cur.mark())
cur.clearSelection();
if (isRTL(cur.paragraph()))
- cursorRightOneWord(cur);
+ needsUpdate = cursorRightOneWord(cur);
else
- cursorLeftOneWord(cur);
+ needsUpdate = cursorLeftOneWord(cur);
finishChange(cur, false);
break;
case LFUN_BEGINNINGBUF:
- if (cur.size() == 1) {
+ if (cur.depth() == 1) {
if (!cur.mark())
cur.clearSelection();
cursorTop(cur);
break;
case LFUN_BEGINNINGBUFSEL:
- if (cur.size() == 1) {
+ if (cur.depth() == 1) {
if (!cur.selection())
cur.resetAnchor();
cursorTop(cur);
break;
case LFUN_ENDBUF:
- if (cur.size() == 1) {
+ if (cur.depth() == 1) {
if (!cur.mark())
cur.clearSelection();
cursorBottom(cur);
break;
case LFUN_ENDBUFSEL:
- if (cur.size() == 1) {
+ if (cur.depth() == 1) {
if (!cur.selection())
cur.resetAnchor();
cursorBottom(cur);
break;
case LFUN_RIGHT:
- moving = true;
case LFUN_RIGHTSEL:
- //lyxerr << "handle LFUN_RIGHT[SEL]:\n" << cur << endl;
+ lyxerr << BOOST_CURRENT_FUNCTION
+ << " LFUN_RIGHT[SEL]:\n" << cur << endl;
cur.selHandle(cmd.action == LFUN_RIGHTSEL);
if (isRTL(cur.paragraph()))
- cursorLeft(cur);
+ needsUpdate = cursorLeft(cur);
else
- cursorRight(cur);
- if (sl == cur.top()) {
+ needsUpdate = cursorRight(cur);
+ if (!needsUpdate && oldTopSlice == cur.top()) {
cur.undispatched();
cmd = FuncRequest(LFUN_FINISHED_RIGHT);
}
break;
case LFUN_LEFT:
- moving = true;
case LFUN_LEFTSEL:
//lyxerr << "handle LFUN_LEFT[SEL]:\n" << cur << endl;
cur.selHandle(cmd.action == LFUN_LEFTSEL);
if (isRTL(cur.paragraph()))
- cursorRight(cur);
+ needsUpdate = cursorRight(cur);
else
- cursorLeft(cur);
- if (sl == cur.top()) {
+ needsUpdate = cursorLeft(cur);
+ if (oldTopSlice == cur.top()) {
cur.undispatched();
cmd = FuncRequest(LFUN_FINISHED_LEFT);
}
break;
case LFUN_UP:
- moving = true;
case LFUN_UPSEL:
update(cur);
//lyxerr << "handle LFUN_UP[SEL]:\n" << cur << endl;
cur.selHandle(cmd.action == LFUN_UPSEL);
- cursorUp(cur);
- if (sl == cur.top()) {
+ needsUpdate = cursorUp(cur);
+ if (oldTopSlice == cur.top()) {
cur.undispatched();
cmd = FuncRequest(LFUN_FINISHED_UP);
}
break;
case LFUN_DOWN:
- moving = true;
case LFUN_DOWNSEL:
update(cur);
//lyxerr << "handle LFUN_DOWN[SEL]:\n" << cur << endl;
cur.selHandle(cmd.action == LFUN_DOWNSEL);
- cursorDown(cur);
- if (sl == cur.top()) {
+ needsUpdate = cursorDown(cur);
+ if (oldTopSlice == cur.top()) {
cur.undispatched();
cmd = FuncRequest(LFUN_FINISHED_DOWN);
}
break;
+ case LFUN_UP_PARAGRAPH:
+ if (!cur.mark())
+ cur.clearSelection();
+ needsUpdate = cursorUpParagraph(cur);
+ finishChange(cur, false);
+ break;
+
case LFUN_UP_PARAGRAPHSEL:
if (!cur.selection())
cur.resetAnchor();
finishChange(cur, true);
break;
+ case LFUN_DOWN_PARAGRAPH:
+ if (!cur.mark())
+ cur.clearSelection();
+ needsUpdate = cursorDownParagraph(cur);
+ finishChange(cur, false);
+ break;
+
case LFUN_DOWN_PARAGRAPHSEL:
if (!cur.selection())
cur.resetAnchor();
break;
}
- case LFUN_UP_PARAGRAPH:
- moving = true;
- if (!cur.mark())
- cur.clearSelection();
- cursorUpParagraph(cur);
- finishChange(cur, false);
- break;
-
- case LFUN_DOWN_PARAGRAPH:
- moving = true;
- if (!cur.mark())
- cur.clearSelection();
- cursorDownParagraph(cur);
- finishChange(cur, false);
- break;
-
case LFUN_PRIOR:
update(cur);
- moving = true;
if (!cur.mark())
cur.clearSelection();
finishChange(cur, false);
cur.undispatched();
cmd = FuncRequest(LFUN_FINISHED_UP);
} else {
- cursorPrevious(cur);
+ needsUpdate = cursorPrevious(cur);
}
break;
case LFUN_NEXT:
update(cur);
- moving = true;
if (!cur.mark())
cur.clearSelection();
finishChange(cur, false);
cur.undispatched();
cmd = FuncRequest(LFUN_FINISHED_DOWN);
} else {
- cursorNext(cur);
+ needsUpdate = cursorNext(cur);
}
break;
break;
}
- case LFUN_INSET_APPLY: {
- string const name = cmd.getArg(0);
- InsetBase * inset = bv->owner()->getDialogs().getOpenInset(name);
- if (inset) {
- FuncRequest fr(LFUN_INSET_MODIFY, cmd.argument);
- inset->dispatch(cur, fr);
- } else {
- FuncRequest fr(LFUN_INSET_INSERT, cmd.argument);
- dispatch(cur, fr);
- }
- break;
- }
-
case LFUN_INSET_INSERT: {
recordUndo(cur);
InsetBase * inset = createInset(bv, cmd);
break;
}
- case LFUN_GOTOERROR:
- gotoInset(cur, InsetBase::ERROR_CODE, false);
- break;
-
- case LFUN_GOTONOTE:
- gotoInset(cur, InsetBase::NOTE_CODE, false);
- break;
-
- case LFUN_REFERENCE_GOTO: {
- vector<InsetBase_code> tmp;
- tmp.push_back(InsetBase::LABEL_CODE);
- tmp.push_back(InsetBase::REF_CODE);
- gotoInset(cur, tmp, true);
- break;
- }
-
case LFUN_QUOTE: {
lyx::cap::replaceSelection(cur);
Paragraph & par = cur.paragraph();
cur.resetAnchor();
cursorEnd(cur);
cur.setSelection();
+ bv->cursor() = cur;
bv->haveSelection(cur.selection());
}
break;
case LFUN_MOUSE_DOUBLE:
if (cmd.button() == mouse_button::button1) {
selectWord(cur, lyx::WHOLE_WORD_STRICT);
+ bv->cursor() = cur;
bv->haveSelection(cur.selection());
}
break;
cur.clearSelection();
LyXFont const old_font = real_current_font;
+ // Prevents language turds in new lyxtexts under non-english
+ BufferParams const & bufparams = cur.buffer().params();
+ Language const * lang = cur.paragraph().getParLanguage(bufparams);
+ current_font.setLanguage(lang);
+ real_current_font.setLanguage(lang);
+
string::const_iterator cit = cmd.argument.begin();
string::const_iterator end = cmd.argument.end();
for (; cit != end; ++cit)
case LFUN_INSERT_BRANCH:
case LFUN_INSERT_BIBITEM:
case LFUN_INSET_ERT:
- case LFUN_INSET_FLOAT:
case LFUN_INSET_FOOTNOTE:
case LFUN_INSET_MARGINAL:
case LFUN_INSET_OPTARG:
- case LFUN_INSET_WIDE_FLOAT:
- case LFUN_INSET_WRAP:
case LFUN_TABULAR_INSERT:
case LFUN_ENVIRONMENT_INSERT:
// Open the inset, and move the current selection
cur.posRight();
break;
+ case LFUN_INSET_FLOAT:
+ case LFUN_INSET_WIDE_FLOAT:
+ case LFUN_INSET_WRAP:
+ doInsertInset(cur, this, cmd, true, true);
+ cur.posRight();
+ // FIXME: the "Caption" name should not be hardcoded,
+ // but given by the float definition.
+ cur.dispatch(FuncRequest(LFUN_LAYOUT, "Caption"));
+ break;
+
case LFUN_INDEX_INSERT:
// Just open the inset
doInsertInset(cur, this, cmd, true, false);
break;
default:
+ lyxerr << BOOST_CURRENT_FUNCTION
+ << " Not DISPATCHED by LyXText" << endl;
cur.undispatched();
break;
}
- // avoid to update when navigating
- if (moving
- && &sl.inset() == &cur.inset()
- && sl.idx() == cur.idx()
- && sel == false
- && cur.selection() == false)
+ if (!needsUpdate
+ && &oldTopSlice.inset() == &cur.inset()
+ && oldTopSlice.idx() == cur.idx()
+ && !sel
+ && !cur.selection())
cur.noUpdate();
+ else
+ cur.needsUpdate();
}
case LFUN_APPENDIX:
flag.setOnOff(cur.paragraph().params().startOfAppendix());
- break;
+ return true;
#if 0
// the functions which insert insets
case LFUN_INSET_DIALOG_SHOW:
break;
+ case LFUN_INSET_MODIFY:
+ // We need to disable this, because we may get called for a
+ // tabular cell via
+ // InsetTabular::getStatus() -> InsetText::getStatus()
+ // and we don't handle LFUN_INSET_MODIFY.
+ enable = false;
+ break;
+
case LFUN_EMPH:
flag.setOnOff(font.emph() == LyXFont::ON);
- break;
+ return true;
case LFUN_NOUN:
flag.setOnOff(font.noun() == LyXFont::ON);
- break;
+ return true;
case LFUN_BOLD:
flag.setOnOff(font.series() == LyXFont::BOLD_SERIES);
- break;
+ return true;
case LFUN_SANS:
flag.setOnOff(font.family() == LyXFont::SANS_FAMILY);
- break;
+ return true;
case LFUN_ROMAN:
flag.setOnOff(font.family() == LyXFont::ROMAN_FAMILY);
- break;
+ return true;
case LFUN_CODE:
flag.setOnOff(font.family() == LyXFont::TYPEWRITER_FAMILY);
- break;
+ return true;
case LFUN_DELETE_WORD_FORWARD:
case LFUN_DELETE_WORD_BACKWARD:
case LFUN_BREAKPARAGRAPHKEEPLAYOUT:
case LFUN_BREAKPARAGRAPH_SKIP:
case LFUN_PARAGRAPH_SPACING:
- case LFUN_INSET_APPLY:
case LFUN_INSET_INSERT:
case LFUN_NEXT_INSET_TOGGLE:
case LFUN_UPCASE_WORD:
case LFUN_GETLAYOUT:
case LFUN_LAYOUT:
case LFUN_PASTESELECTION:
- case LFUN_GOTOERROR:
- case LFUN_GOTONOTE:
- case LFUN_REFERENCE_GOTO:
case LFUN_DATE_INSERT:
case LFUN_SELFINSERT:
case LFUN_INSERT_LABEL: