2003-08-23 00:17:00 +00:00
|
|
|
/**
|
2008-11-16 16:43:49 +00:00
|
|
|
* \file Text3.cpp
|
2003-08-23 00:17:00 +00:00
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
* Licence details can be found in the file COPYING.
|
2002-08-20 13:00:25 +00:00
|
|
|
*
|
2003-08-23 00:17:00 +00:00
|
|
|
* \author Asger Alstrup
|
2008-11-14 15:58:50 +00:00
|
|
|
* \author Lars Gullik Bjønnes
|
2003-08-23 00:17:00 +00:00
|
|
|
* \author Alfredo Braunstein
|
|
|
|
* \author Angus Leeming
|
|
|
|
* \author John Levon
|
2008-11-14 15:58:50 +00:00
|
|
|
* \author André Pönitz
|
2002-08-20 13:00:25 +00:00
|
|
|
*
|
2003-08-23 00:17:00 +00:00
|
|
|
* Full author contact details are available in file CREDITS.
|
|
|
|
*/
|
2002-08-20 13:00:25 +00:00
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
2007-04-29 23:33:02 +00:00
|
|
|
#include "Text.h"
|
2003-09-06 18:38:02 +00:00
|
|
|
|
2005-11-02 11:27:08 +00:00
|
|
|
#include "BranchList.h"
|
2004-03-18 13:57:20 +00:00
|
|
|
#include "FloatList.h"
|
|
|
|
#include "FuncStatus.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
#include "Buffer.h"
|
2005-02-25 11:55:36 +00:00
|
|
|
#include "buffer_funcs.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
#include "BufferParams.h"
|
2002-08-20 13:00:25 +00:00
|
|
|
#include "BufferView.h"
|
2009-05-01 17:06:36 +00:00
|
|
|
#include "Changes.h"
|
2007-04-26 14:56:30 +00:00
|
|
|
#include "Cursor.h"
|
2004-03-25 09:16:36 +00:00
|
|
|
#include "CutAndPaste.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
#include "DispatchResult.h"
|
|
|
|
#include "ErrorList.h"
|
2003-09-06 18:38:02 +00:00
|
|
|
#include "factory.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
#include "FuncRequest.h"
|
2007-10-24 15:32:43 +00:00
|
|
|
#include "InsetList.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
#include "Intl.h"
|
|
|
|
#include "Language.h"
|
2007-09-29 20:02:32 +00:00
|
|
|
#include "Layout.h"
|
2005-02-08 02:06:39 +00:00
|
|
|
#include "LyXAction.h"
|
2010-02-09 16:11:13 +00:00
|
|
|
#include "LyX.h"
|
2007-04-26 11:30:54 +00:00
|
|
|
#include "Lexer.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
#include "LyXRC.h"
|
|
|
|
#include "Paragraph.h"
|
2002-08-20 13:00:25 +00:00
|
|
|
#include "ParagraphParameters.h"
|
2010-01-19 08:21:56 +00:00
|
|
|
#include "SpellChecker.h"
|
2007-11-07 23:25:08 +00:00
|
|
|
#include "TextClass.h"
|
2007-10-11 09:59:01 +00:00
|
|
|
#include "TextMetrics.h"
|
2015-07-16 20:06:23 +00:00
|
|
|
#include "Thesaurus.h"
|
2010-01-19 08:21:56 +00:00
|
|
|
#include "WordLangTuple.h"
|
2003-09-06 18:38:02 +00:00
|
|
|
|
2015-04-12 13:55:01 +00:00
|
|
|
#include "frontends/alert.h"
|
2008-11-16 00:12:21 +00:00
|
|
|
#include "frontends/Application.h"
|
2008-12-21 01:54:04 +00:00
|
|
|
#include "frontends/Clipboard.h"
|
|
|
|
#include "frontends/Selection.h"
|
2003-09-06 18:38:02 +00:00
|
|
|
|
2012-11-19 13:21:02 +00:00
|
|
|
#include "insets/InsetArgument.h"
|
2017-10-16 08:12:21 +00:00
|
|
|
#include "insets/InsetCollapsible.h"
|
2007-04-25 01:24:38 +00:00
|
|
|
#include "insets/InsetCommand.h"
|
2008-12-21 01:53:47 +00:00
|
|
|
#include "insets/InsetExternal.h"
|
2009-07-21 20:04:52 +00:00
|
|
|
#include "insets/InsetFloat.h"
|
2007-04-25 01:24:38 +00:00
|
|
|
#include "insets/InsetFloatList.h"
|
2008-12-21 01:54:04 +00:00
|
|
|
#include "insets/InsetGraphics.h"
|
|
|
|
#include "insets/InsetGraphicsParams.h"
|
2012-08-23 15:42:53 +00:00
|
|
|
#include "insets/InsetIPAMacro.h"
|
2007-04-25 01:24:38 +00:00
|
|
|
#include "insets/InsetNewline.h"
|
|
|
|
#include "insets/InsetQuotes.h"
|
|
|
|
#include "insets/InsetSpecialChar.h"
|
|
|
|
#include "insets/InsetText.h"
|
2009-07-21 20:04:52 +00:00
|
|
|
#include "insets/InsetWrap.h"
|
2003-09-06 18:38:02 +00:00
|
|
|
|
2005-01-06 16:39:35 +00:00
|
|
|
#include "support/convert.h"
|
2008-02-09 10:41:49 +00:00
|
|
|
#include "support/debug.h"
|
|
|
|
#include "support/gettext.h"
|
2011-07-14 17:00:35 +00:00
|
|
|
#include "support/lassert.h"
|
2008-02-09 10:41:49 +00:00
|
|
|
#include "support/lstrings.h"
|
2015-05-15 22:05:23 +00:00
|
|
|
#include "support/lyxalgo.h"
|
2005-07-05 09:01:52 +00:00
|
|
|
#include "support/lyxtime.h"
|
2009-03-27 11:22:54 +00:00
|
|
|
#include "support/os.h"
|
2014-02-23 16:20:47 +00:00
|
|
|
#include "support/regex.h"
|
2003-11-10 09:06:48 +00:00
|
|
|
|
2006-09-17 09:14:18 +00:00
|
|
|
#include "mathed/InsetMathHull.h"
|
2017-07-05 12:31:28 +00:00
|
|
|
#include "mathed/InsetMathMacroTemplate.h"
|
2003-11-10 09:06:48 +00:00
|
|
|
|
2003-09-05 22:17:02 +00:00
|
|
|
#include <clocale>
|
2004-07-24 10:55:30 +00:00
|
|
|
#include <sstream>
|
2002-08-27 13:39:27 +00:00
|
|
|
|
2007-12-12 10:16:00 +00:00
|
|
|
using namespace std;
|
2007-12-12 18:57:56 +00:00
|
|
|
using namespace lyx::support;
|
2003-09-09 22:13:45 +00:00
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
namespace lyx {
|
2004-03-25 09:16:36 +00:00
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
using cap::copySelection;
|
|
|
|
using cap::cutSelection;
|
2016-11-09 14:13:41 +00:00
|
|
|
using cap::cutSelectionToTemp;
|
2007-02-02 03:10:15 +00:00
|
|
|
using cap::pasteFromStack;
|
2016-11-09 14:13:41 +00:00
|
|
|
using cap::pasteFromTemp;
|
2008-02-03 10:43:03 +00:00
|
|
|
using cap::pasteClipboardText;
|
|
|
|
using cap::pasteClipboardGraphics;
|
2006-10-21 00:16:43 +00:00
|
|
|
using cap::replaceSelection;
|
2008-11-16 00:12:21 +00:00
|
|
|
using cap::grabAndEraseSelection;
|
|
|
|
using cap::selClearOrDel;
|
2011-10-29 15:42:01 +00:00
|
|
|
using cap::pasteSimpleText;
|
2016-06-26 16:22:59 +00:00
|
|
|
using frontend::Clipboard;
|
2006-10-21 00:16:43 +00:00
|
|
|
|
2007-09-29 11:00:18 +00:00
|
|
|
// globals...
|
2007-11-14 15:07:08 +00:00
|
|
|
static Font freefont(ignore_font, ignore_language);
|
2007-09-29 11:00:18 +00:00
|
|
|
static bool toggleall = false;
|
2002-08-27 13:17:22 +00:00
|
|
|
|
2007-09-29 11:00:18 +00:00
|
|
|
static void toggleAndShow(Cursor & cur, Text * text,
|
|
|
|
Font const & font, bool toggleall = true)
|
|
|
|
{
|
|
|
|
text->toggleFree(cur, font, toggleall);
|
|
|
|
|
|
|
|
if (font.language() != ignore_language ||
|
2007-11-06 17:13:43 +00:00
|
|
|
font.fontInfo().number() != FONT_IGNORE) {
|
2007-09-29 11:00:18 +00:00
|
|
|
TextMetrics const & tm = cur.bv().textMetrics(text);
|
2007-11-06 17:13:43 +00:00
|
|
|
if (cur.boundary() != tm.isRTLBoundary(cur.pit(), cur.pos(),
|
|
|
|
cur.real_current_font))
|
2007-09-29 11:00:18 +00:00
|
|
|
text->setCursor(cur, cur.pit(), cur.pos(),
|
2007-11-06 17:13:43 +00:00
|
|
|
false, !cur.boundary());
|
2003-11-10 09:06:48 +00:00
|
|
|
}
|
2007-09-29 11:00:18 +00:00
|
|
|
}
|
2003-11-10 09:06:48 +00:00
|
|
|
|
|
|
|
|
2007-09-29 11:00:18 +00:00
|
|
|
static void moveCursor(Cursor & cur, bool selecting)
|
|
|
|
{
|
|
|
|
if (selecting || cur.mark())
|
|
|
|
cur.setSelection();
|
|
|
|
}
|
2002-08-27 14:43:49 +00:00
|
|
|
|
|
|
|
|
2007-09-29 11:00:18 +00:00
|
|
|
static void finishChange(Cursor & cur, bool selecting)
|
|
|
|
{
|
2007-10-18 11:51:17 +00:00
|
|
|
cur.finishUndo();
|
2007-09-29 11:00:18 +00:00
|
|
|
moveCursor(cur, selecting);
|
|
|
|
}
|
2002-08-27 13:17:22 +00:00
|
|
|
|
2004-02-11 14:45:44 +00:00
|
|
|
|
2015-08-01 07:05:33 +00:00
|
|
|
static void mathDispatch(Cursor & cur, FuncRequest const & cmd)
|
2007-09-29 11:00:18 +00:00
|
|
|
{
|
2007-10-18 11:51:17 +00:00
|
|
|
cur.recordUndo();
|
2007-09-29 11:00:18 +00:00
|
|
|
docstring sel = cur.selectionAsString(false);
|
2004-02-11 14:45:44 +00:00
|
|
|
|
2007-09-29 11:00:18 +00:00
|
|
|
// It may happen that sel is empty but there is a selection
|
|
|
|
replaceSelection(cur);
|
2006-02-24 12:58:31 +00:00
|
|
|
|
2008-10-06 22:49:30 +00:00
|
|
|
// Is this a valid formula?
|
|
|
|
bool valid = true;
|
|
|
|
|
2007-09-29 11:00:18 +00:00
|
|
|
if (sel.empty()) {
|
2007-01-04 14:28:22 +00:00
|
|
|
#ifdef ENABLE_ASSERTIONS
|
2007-09-29 11:00:18 +00:00
|
|
|
const int old_pos = cur.pos();
|
2007-01-04 14:28:22 +00:00
|
|
|
#endif
|
2009-11-08 11:45:46 +00:00
|
|
|
cur.insert(new InsetMathHull(cur.buffer(), hullSimple));
|
2008-04-15 17:26:19 +00:00
|
|
|
#ifdef ENABLE_ASSERTIONS
|
2013-04-25 21:27:10 +00:00
|
|
|
LATTEST(old_pos == cur.pos());
|
2008-04-15 17:26:19 +00:00
|
|
|
#endif
|
2007-09-29 11:00:18 +00:00
|
|
|
cur.nextInset()->edit(cur, true);
|
2015-08-01 07:05:33 +00:00
|
|
|
if (cmd.action() != LFUN_MATH_MODE)
|
|
|
|
// LFUN_MATH_MODE has a different meaning in math mode
|
|
|
|
cur.dispatch(cmd);
|
2007-09-29 11:00:18 +00:00
|
|
|
} else {
|
2015-08-01 07:05:33 +00:00
|
|
|
InsetMathHull * formula = new InsetMathHull(cur.buffer());
|
|
|
|
string const selstr = to_utf8(sel);
|
|
|
|
istringstream is(selstr);
|
|
|
|
Lexer lex;
|
|
|
|
lex.setStream(is);
|
|
|
|
if (!formula->readQuiet(lex)) {
|
|
|
|
// No valid formula, let's try with delims
|
|
|
|
is.str("$" + selstr + "$");
|
2007-09-29 11:00:18 +00:00
|
|
|
lex.setStream(is);
|
2008-10-31 15:19:39 +00:00
|
|
|
if (!formula->readQuiet(lex)) {
|
2015-08-01 07:05:33 +00:00
|
|
|
// Still not valid, leave it as is
|
|
|
|
valid = false;
|
|
|
|
delete formula;
|
|
|
|
cur.insert(sel);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (valid) {
|
|
|
|
cur.insert(formula);
|
|
|
|
cur.nextInset()->edit(cur, true);
|
|
|
|
LASSERT(cur.inMathed(), return);
|
|
|
|
cur.pos() = 0;
|
|
|
|
cur.resetAnchor();
|
2016-02-28 16:36:29 +00:00
|
|
|
cur.selection(true);
|
2015-08-01 07:05:33 +00:00
|
|
|
cur.pos() = cur.lastpos();
|
|
|
|
if (cmd.action() != LFUN_MATH_MODE)
|
|
|
|
// LFUN_MATH_MODE has a different meaning in math mode
|
|
|
|
cur.dispatch(cmd);
|
|
|
|
cur.clearSelection();
|
|
|
|
cur.pos() = cur.lastpos();
|
2004-02-11 14:45:44 +00:00
|
|
|
}
|
|
|
|
}
|
2008-10-06 22:49:30 +00:00
|
|
|
if (valid)
|
|
|
|
cur.message(from_utf8(N_("Math editor mode")));
|
|
|
|
else
|
|
|
|
cur.message(from_utf8(N_("No valid math formula")));
|
2003-11-10 09:06:48 +00:00
|
|
|
}
|
|
|
|
|
2002-08-22 13:02:14 +00:00
|
|
|
|
2008-11-16 00:12:21 +00:00
|
|
|
void regexpDispatch(Cursor & cur, FuncRequest const & cmd)
|
|
|
|
{
|
2010-04-09 19:00:42 +00:00
|
|
|
LASSERT(cmd.action() == LFUN_REGEXP_MODE, return);
|
2008-11-16 00:12:21 +00:00
|
|
|
if (cur.inRegexped()) {
|
2010-01-28 19:56:12 +00:00
|
|
|
cur.message(_("Already in regular expression mode"));
|
2008-11-16 00:12:21 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
cur.recordUndo();
|
2009-08-15 22:53:15 +00:00
|
|
|
docstring sel = cur.selectionAsString(false);
|
|
|
|
|
|
|
|
// It may happen that sel is empty but there is a selection
|
|
|
|
replaceSelection(cur);
|
2008-11-16 00:12:21 +00:00
|
|
|
|
2009-11-08 11:45:46 +00:00
|
|
|
cur.insert(new InsetMathHull(cur.buffer(), hullRegexp));
|
2008-11-16 00:12:21 +00:00
|
|
|
cur.nextInset()->edit(cur, true);
|
2009-08-15 22:53:15 +00:00
|
|
|
cur.niceInsert(sel);
|
2008-11-16 00:12:21 +00:00
|
|
|
|
|
|
|
cur.message(_("Regexp editor mode"));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-09-29 11:00:18 +00:00
|
|
|
static void specialChar(Cursor & cur, InsetSpecialChar::Kind kind)
|
2002-08-20 13:00:25 +00:00
|
|
|
{
|
2007-10-18 11:51:17 +00:00
|
|
|
cur.recordUndo();
|
2006-10-21 00:16:43 +00:00
|
|
|
cap::replaceSelection(cur);
|
2004-02-13 07:30:59 +00:00
|
|
|
cur.insert(new InsetSpecialChar(kind));
|
2007-11-05 19:41:16 +00:00
|
|
|
cur.posForward();
|
2002-08-20 13:00:25 +00:00
|
|
|
}
|
|
|
|
|
2003-02-18 11:47:16 +00:00
|
|
|
|
2012-08-23 15:42:53 +00:00
|
|
|
static void ipaChar(Cursor & cur, InsetIPAChar::Kind kind)
|
|
|
|
{
|
|
|
|
cur.recordUndo();
|
|
|
|
cap::replaceSelection(cur);
|
|
|
|
cur.insert(new InsetIPAChar(kind));
|
|
|
|
cur.posForward();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-09-29 11:00:18 +00:00
|
|
|
static bool doInsertInset(Cursor & cur, Text * text,
|
2004-02-13 07:30:59 +00:00
|
|
|
FuncRequest const & cmd, bool edit, bool pastesel)
|
2003-01-17 09:57:50 +00:00
|
|
|
{
|
2008-02-13 12:10:18 +00:00
|
|
|
Buffer & buffer = cur.bv().buffer();
|
|
|
|
BufferParams const & bparams = buffer.params();
|
2009-11-08 15:53:21 +00:00
|
|
|
Inset * inset = createInset(&buffer, cmd);
|
2003-12-12 10:05:21 +00:00
|
|
|
if (!inset)
|
2005-05-30 15:35:11 +00:00
|
|
|
return false;
|
2003-12-12 10:05:21 +00:00
|
|
|
|
2017-10-16 08:12:21 +00:00
|
|
|
if (InsetCollapsible * ci = inset->asInsetCollapsible())
|
2009-07-18 19:35:27 +00:00
|
|
|
ci->setButtonLabel();
|
|
|
|
|
2007-10-18 11:51:17 +00:00
|
|
|
cur.recordUndo();
|
2010-04-09 19:00:42 +00:00
|
|
|
if (cmd.action() == LFUN_INDEX_INSERT) {
|
2007-12-12 19:57:42 +00:00
|
|
|
docstring ds = subst(text->getStringToIndex(cur), '\n', ' ');
|
2007-10-03 13:38:19 +00:00
|
|
|
text->insertInset(cur, inset);
|
|
|
|
if (edit)
|
|
|
|
inset->edit(cur, true);
|
|
|
|
// Now put this into inset
|
2011-02-02 16:43:02 +00:00
|
|
|
Font const f(inherit_font, cur.current_font.language());
|
2011-11-22 18:40:01 +00:00
|
|
|
if (!ds.empty()) {
|
|
|
|
cur.text()->insertStringAsLines(cur, ds, f);
|
|
|
|
cur.leaveInset(*inset);
|
|
|
|
}
|
2008-02-09 10:45:49 +00:00
|
|
|
return true;
|
|
|
|
}
|
2015-05-09 10:17:24 +00:00
|
|
|
else if (cmd.action() == LFUN_ARGUMENT_INSERT) {
|
|
|
|
bool cotextinsert = false;
|
|
|
|
InsetArgument const * const ia = static_cast<InsetArgument const *>(inset);
|
|
|
|
Layout const & lay = cur.paragraph().layout();
|
|
|
|
Layout::LaTeXArgMap args = lay.args();
|
|
|
|
Layout::LaTeXArgMap::const_iterator const lait = args.find(ia->name());
|
|
|
|
if (lait != args.end())
|
|
|
|
cotextinsert = (*lait).second.insertcotext;
|
2015-05-21 06:53:56 +00:00
|
|
|
else {
|
|
|
|
InsetLayout const & il = cur.inset().getLayout();
|
|
|
|
args = il.args();
|
|
|
|
Layout::LaTeXArgMap::const_iterator const ilait = args.find(ia->name());
|
|
|
|
if (ilait != args.end())
|
|
|
|
cotextinsert = (*ilait).second.insertcotext;
|
|
|
|
}
|
2015-05-09 10:17:24 +00:00
|
|
|
// The argument requests to insert a copy of the co-text to the inset
|
|
|
|
if (cotextinsert) {
|
|
|
|
docstring ds;
|
|
|
|
// If we have a selection within a paragraph, use this
|
|
|
|
if (cur.selection() && cur.selBegin().pit() == cur.selEnd().pit())
|
|
|
|
ds = cur.selectionAsString(false);
|
|
|
|
// else use the whole paragraph
|
|
|
|
else
|
|
|
|
ds = cur.paragraph().asString();
|
|
|
|
text->insertInset(cur, inset);
|
|
|
|
if (edit)
|
|
|
|
inset->edit(cur, true);
|
|
|
|
// Now put co-text into inset
|
|
|
|
Font const f(inherit_font, cur.current_font.language());
|
|
|
|
if (!ds.empty()) {
|
|
|
|
cur.text()->insertStringAsLines(cur, ds, f);
|
|
|
|
cur.leaveInset(*inset);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2007-10-03 13:38:19 +00:00
|
|
|
|
2008-02-09 10:45:49 +00:00
|
|
|
bool gotsel = false;
|
|
|
|
if (cur.selection()) {
|
2016-11-09 14:13:41 +00:00
|
|
|
cutSelectionToTemp(cur, false, pastesel);
|
2008-07-14 19:47:43 +00:00
|
|
|
cur.clearSelection();
|
2008-02-09 10:45:49 +00:00
|
|
|
gotsel = true;
|
|
|
|
}
|
|
|
|
text->insertInset(cur, inset);
|
|
|
|
|
|
|
|
if (edit)
|
|
|
|
inset->edit(cur, true);
|
|
|
|
|
|
|
|
if (!gotsel || !pastesel)
|
|
|
|
return true;
|
|
|
|
|
2016-11-09 14:13:41 +00:00
|
|
|
pasteFromTemp(cur, cur.buffer()->errorList("Paste"));
|
2008-11-17 11:46:07 +00:00
|
|
|
cur.buffer()->errors("Paste");
|
2008-07-14 19:47:43 +00:00
|
|
|
cur.clearSelection(); // bug 393
|
|
|
|
cur.finishUndo();
|
Remove unneccessary uses of dynamic_cast from the code.
A dynamic_cast is necessary when:
- the object to be casted is from an external library because we can't add Qxxx::asXxxx() to Qt e.g.:
* QAbstractListModel to GuiIdListModel,
* QValidator to PathValidator,
* QWidget to TabWorkArea,
* QWidget to GuiWorkArea;
- the object is to be casted from an interface to the implementing class, because the Interface does not know by whom it is implemented:
* ProgressInterface to GuiProgress,
* Application to GuiApplication.
A dynamic_cast can be replaced by:
- already existing as***Inset() functions, e.g.:
* asHullInset(),
* asInsetMath()->asMacro(),
* asInsetText();
- a static_cast when we are sure this can't go wrong, e.g.:
* we are sure that CellData::inset->clone() is an InsetTableCell,
* in cases where we explicitly check it->lyxCode().
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@35855 a592a061-630c-0410-9148-cb99ea01b6c8
2010-10-26 15:03:51 +00:00
|
|
|
InsetText * inset_text = inset->asInsetText();
|
|
|
|
if (inset_text) {
|
|
|
|
inset_text->fixParagraphsFont();
|
|
|
|
if (!inset_text->allowMultiPar() || cur.lastpit() == 0) {
|
2010-01-03 01:13:55 +00:00
|
|
|
// reset first par to default
|
|
|
|
cur.text()->paragraphs().begin()
|
|
|
|
->setPlainOrDefaultLayout(bparams.documentClass());
|
|
|
|
cur.pos() = 0;
|
|
|
|
cur.pit() = 0;
|
|
|
|
// Merge multiple paragraphs -- hack
|
|
|
|
while (cur.lastpit() > 0)
|
|
|
|
mergeParagraph(bparams, cur.text()->paragraphs(), 0);
|
2012-12-17 12:32:40 +00:00
|
|
|
if (cmd.action() == LFUN_FLEX_INSERT)
|
|
|
|
return true;
|
2012-09-30 16:36:22 +00:00
|
|
|
Cursor old = cur;
|
2010-01-03 01:13:55 +00:00
|
|
|
cur.leaveInset(*inset);
|
2012-09-30 16:36:22 +00:00
|
|
|
if (cmd.action() == LFUN_PREVIEW_INSERT
|
|
|
|
|| cmd.action() == LFUN_IPA_INSERT)
|
|
|
|
// trigger preview
|
|
|
|
notifyCursorLeavesOrEnters(old, cur);
|
2010-01-03 01:13:55 +00:00
|
|
|
}
|
2008-02-09 10:45:49 +00:00
|
|
|
} else {
|
2008-07-14 19:47:43 +00:00
|
|
|
cur.leaveInset(*inset);
|
2008-02-09 10:45:49 +00:00
|
|
|
// reset surrounding par to default
|
2008-08-09 16:56:30 +00:00
|
|
|
DocumentClass const & dc = bparams.documentClass();
|
|
|
|
docstring const layoutname = inset->usePlainLayout()
|
|
|
|
? dc.plainLayoutName()
|
|
|
|
: dc.defaultLayoutName();
|
2008-02-09 10:45:49 +00:00
|
|
|
text->setLayout(cur, layoutname);
|
2006-09-14 13:44:53 +00:00
|
|
|
}
|
2005-05-30 15:35:11 +00:00
|
|
|
return true;
|
2003-01-17 09:57:50 +00:00
|
|
|
}
|
|
|
|
|
2004-11-30 01:59:49 +00:00
|
|
|
|
2007-09-29 11:00:18 +00:00
|
|
|
string const freefont2string()
|
|
|
|
{
|
|
|
|
return freefont.toString(toggleall);
|
|
|
|
}
|
2003-10-13 01:35:47 +00:00
|
|
|
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2009-06-30 00:10:55 +00:00
|
|
|
/// the type of outline operation
|
|
|
|
enum OutlineOp {
|
|
|
|
OutlineUp, // Move this header with text down
|
|
|
|
OutlineDown, // Move this header with text up
|
|
|
|
OutlineIn, // Make this header deeper
|
|
|
|
OutlineOut // Make this header shallower
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2018-01-27 08:59:19 +00:00
|
|
|
static void insertSeparator(Cursor & cur, depth_type const depth)
|
|
|
|
{
|
|
|
|
Buffer & buf = *cur.buffer();
|
|
|
|
lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK));
|
|
|
|
DocumentClass const & tc = buf.params().documentClass();
|
|
|
|
lyx::dispatch(FuncRequest(LFUN_LAYOUT, from_ascii("\"") + tc.plainLayout().name()
|
|
|
|
+ from_ascii("\" ignoreautonests")));
|
|
|
|
// FIXME: Bibitem mess!
|
|
|
|
if (cur.prevInset() && cur.prevInset()->lyxCode() == BIBITEM_CODE)
|
|
|
|
lyx::dispatch(FuncRequest(LFUN_CHAR_DELETE_BACKWARD));
|
|
|
|
lyx::dispatch(FuncRequest(LFUN_SEPARATOR_INSERT, "plain"));
|
|
|
|
while (cur.paragraph().params().depth() > depth)
|
|
|
|
lyx::dispatch(FuncRequest(LFUN_DEPTH_DECREMENT));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void outline(OutlineOp mode, Cursor & cur, Text * text)
|
2007-11-06 17:13:43 +00:00
|
|
|
{
|
2008-11-17 11:46:07 +00:00
|
|
|
Buffer & buf = *cur.buffer();
|
2007-11-06 17:13:43 +00:00
|
|
|
pit_type & pit = cur.pit();
|
|
|
|
ParagraphList & pars = buf.text().paragraphs();
|
2009-05-09 15:49:09 +00:00
|
|
|
ParagraphList::iterator const bgn = pars.begin();
|
2007-11-06 17:13:43 +00:00
|
|
|
// The first paragraph of the area to be copied:
|
2016-01-10 16:59:42 +00:00
|
|
|
ParagraphList::iterator start = lyx::next(bgn, pit);
|
2007-11-06 17:13:43 +00:00
|
|
|
// The final paragraph of area to be copied:
|
|
|
|
ParagraphList::iterator finish = start;
|
2009-05-09 15:49:09 +00:00
|
|
|
ParagraphList::iterator const end = pars.end();
|
2018-01-27 08:59:19 +00:00
|
|
|
depth_type const current_depth = cur.paragraph().params().depth();
|
2007-11-06 17:13:43 +00:00
|
|
|
|
2012-12-15 15:47:57 +00:00
|
|
|
int const thistoclevel = buf.text().getTocLevel(distance(bgn, start));
|
2007-11-06 17:13:43 +00:00
|
|
|
int toclevel;
|
2008-03-02 08:53:34 +00:00
|
|
|
|
|
|
|
// Move out (down) from this section header
|
|
|
|
if (finish != end)
|
|
|
|
++finish;
|
2009-06-30 00:10:55 +00:00
|
|
|
|
2008-03-02 08:53:34 +00:00
|
|
|
// Seek the one (on same level) below
|
|
|
|
for (; finish != end; ++finish) {
|
2012-12-15 15:47:57 +00:00
|
|
|
toclevel = buf.text().getTocLevel(distance(bgn, finish));
|
2009-05-03 18:58:00 +00:00
|
|
|
if (toclevel != Layout::NOT_IN_TOC && toclevel <= thistoclevel)
|
2008-03-02 08:53:34 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2007-11-06 17:13:43 +00:00
|
|
|
switch (mode) {
|
|
|
|
case OutlineUp: {
|
2008-04-21 08:22:52 +00:00
|
|
|
if (start == pars.begin())
|
|
|
|
// Nothing to move.
|
|
|
|
return;
|
2007-11-06 17:13:43 +00:00
|
|
|
ParagraphList::iterator dest = start;
|
|
|
|
// Move out (up) from this header
|
|
|
|
if (dest == bgn)
|
2008-03-02 08:53:34 +00:00
|
|
|
return;
|
2007-11-06 17:13:43 +00:00
|
|
|
// Search previous same-level header above
|
|
|
|
do {
|
|
|
|
--dest;
|
2012-12-15 15:47:57 +00:00
|
|
|
toclevel = buf.text().getTocLevel(distance(bgn, dest));
|
2007-11-06 17:13:43 +00:00
|
|
|
} while(dest != bgn
|
|
|
|
&& (toclevel == Layout::NOT_IN_TOC
|
|
|
|
|| toclevel > thistoclevel));
|
|
|
|
// Not found; do nothing
|
|
|
|
if (toclevel == Layout::NOT_IN_TOC || toclevel > thistoclevel)
|
2008-03-02 08:53:34 +00:00
|
|
|
return;
|
2018-01-27 08:59:19 +00:00
|
|
|
pit_type newpit = distance(bgn, dest);
|
2007-12-12 19:28:07 +00:00
|
|
|
pit_type const len = distance(start, finish);
|
2007-11-06 17:13:43 +00:00
|
|
|
pit_type const deletepit = pit + len;
|
2015-03-12 14:57:29 +00:00
|
|
|
buf.undo().recordUndo(cur, newpit, deletepit - 1);
|
2018-01-27 08:59:19 +00:00
|
|
|
// If we move an environment upwards, make sure it is
|
|
|
|
// separated from its new neighbour below:
|
|
|
|
// If an environment of the same layout follows, and the moved
|
|
|
|
// paragraph sequence does not end with a separator, insert one.
|
|
|
|
ParagraphList::iterator lastmoved = finish;
|
|
|
|
--lastmoved;
|
|
|
|
if (start->layout().isEnvironment()
|
|
|
|
&& dest->layout() == start->layout()
|
|
|
|
&& !lastmoved->isEnvSeparator(lastmoved->beginOfBody())) {
|
|
|
|
cur.pit() = distance(bgn, lastmoved);
|
|
|
|
cur.pos() = cur.lastpos();
|
|
|
|
insertSeparator(cur, current_depth);
|
|
|
|
cur.pit() = pit;
|
|
|
|
}
|
|
|
|
// Likewise, if we moved an environment upwards, make sure it
|
|
|
|
// is separated from its new neighbour above.
|
|
|
|
// The paragraph before the target of movement
|
|
|
|
if (dest != bgn) {
|
|
|
|
ParagraphList::iterator before = dest;
|
|
|
|
--before;
|
|
|
|
// Get the parent paragraph (outer in nested context)
|
|
|
|
pit_type const parent =
|
|
|
|
before->params().depth() > current_depth
|
|
|
|
? text->depthHook(distance(bgn, before), current_depth)
|
|
|
|
: distance(bgn, before);
|
|
|
|
// If a environment with same layout preceeds the moved one in the new
|
|
|
|
// position, and there is no separator yet, insert one.
|
|
|
|
if (start->layout().isEnvironment()
|
|
|
|
&& pars[parent].layout() == start->layout()
|
|
|
|
&& !before->isEnvSeparator(before->beginOfBody())) {
|
|
|
|
cur.pit() = distance(bgn, before);
|
|
|
|
cur.pos() = cur.lastpos();
|
|
|
|
insertSeparator(cur, current_depth);
|
|
|
|
cur.pit() = pit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
newpit = distance(bgn, dest);
|
2009-08-09 20:25:20 +00:00
|
|
|
pars.splice(dest, start, finish);
|
|
|
|
cur.pit() = newpit;
|
2009-05-09 15:49:09 +00:00
|
|
|
break;
|
2007-11-06 17:13:43 +00:00
|
|
|
}
|
|
|
|
case OutlineDown: {
|
2008-04-21 08:22:52 +00:00
|
|
|
if (finish == end)
|
|
|
|
// Nothing to move.
|
|
|
|
return;
|
|
|
|
// Go one down from *this* header:
|
2015-05-15 22:05:23 +00:00
|
|
|
ParagraphList::iterator dest = next(finish, 1);
|
2008-04-21 08:22:52 +00:00
|
|
|
// Go further down to find header to insert in front of:
|
|
|
|
for (; dest != end; ++dest) {
|
2012-12-15 15:47:57 +00:00
|
|
|
toclevel = buf.text().getTocLevel(distance(bgn, dest));
|
2008-04-21 08:22:52 +00:00
|
|
|
if (toclevel != Layout::NOT_IN_TOC
|
2009-05-03 18:58:00 +00:00
|
|
|
&& toclevel <= thistoclevel)
|
2008-04-21 08:22:52 +00:00
|
|
|
break;
|
|
|
|
}
|
2018-01-27 08:59:19 +00:00
|
|
|
// One such was found, so go on...
|
|
|
|
// If we move an environment downwards, make sure it is
|
|
|
|
// separated from its new neighbour above.
|
2008-04-21 08:31:41 +00:00
|
|
|
pit_type newpit = distance(bgn, dest);
|
2015-03-12 14:57:29 +00:00
|
|
|
buf.undo().recordUndo(cur, pit, newpit - 1);
|
2018-01-27 08:59:19 +00:00
|
|
|
// The paragraph before the target of movement
|
|
|
|
ParagraphList::iterator before = dest;
|
|
|
|
--before;
|
|
|
|
// Get the parent paragraph (outer in nested context)
|
|
|
|
pit_type const parent =
|
|
|
|
before->params().depth() > current_depth
|
|
|
|
? text->depthHook(distance(bgn, before), current_depth)
|
|
|
|
: distance(bgn, before);
|
|
|
|
// If a environment with same layout preceeds the moved one in the new
|
|
|
|
// position, and there is no separator yet, insert one.
|
|
|
|
if (start->layout().isEnvironment()
|
|
|
|
&& pars[parent].layout() == start->layout()
|
|
|
|
&& !before->isEnvSeparator(before->beginOfBody())) {
|
|
|
|
cur.pit() = distance(bgn, before);
|
|
|
|
cur.pos() = cur.lastpos();
|
|
|
|
insertSeparator(cur, current_depth);
|
|
|
|
cur.pit() = pit;
|
|
|
|
}
|
|
|
|
// Likewise, make sure moved environments are separated
|
|
|
|
// from their new neighbour below:
|
|
|
|
// If an environment of the same layout follows, and the moved
|
|
|
|
// paragraph sequence does not end with a separator, insert one.
|
|
|
|
ParagraphList::iterator lastmoved = finish;
|
|
|
|
--lastmoved;
|
|
|
|
if (dest != end
|
|
|
|
&& start->layout().isEnvironment()
|
|
|
|
&& dest->layout() == start->layout()
|
|
|
|
&& !lastmoved->isEnvSeparator(lastmoved->beginOfBody())) {
|
|
|
|
cur.pit() = distance(bgn, lastmoved);
|
|
|
|
cur.pos() = cur.lastpos();
|
|
|
|
insertSeparator(cur, current_depth);
|
|
|
|
cur.pit() = pit;
|
|
|
|
}
|
|
|
|
newpit = distance(bgn, dest);
|
2009-08-09 20:25:20 +00:00
|
|
|
pit_type const len = distance(start, finish);
|
|
|
|
pars.splice(dest, start, finish);
|
|
|
|
cur.pit() = newpit - len;
|
2009-05-09 15:49:09 +00:00
|
|
|
break;
|
2007-11-06 17:13:43 +00:00
|
|
|
}
|
2014-06-07 04:41:20 +00:00
|
|
|
case OutlineIn:
|
|
|
|
case OutlineOut: {
|
2008-03-02 09:17:10 +00:00
|
|
|
pit_type const len = distance(start, finish);
|
2015-03-12 14:57:29 +00:00
|
|
|
buf.undo().recordUndo(cur, pit, pit + len - 1);
|
2008-03-02 08:53:34 +00:00
|
|
|
for (; start != finish; ++start) {
|
2012-12-15 15:47:57 +00:00
|
|
|
toclevel = buf.text().getTocLevel(distance(bgn, start));
|
2008-03-02 08:53:34 +00:00
|
|
|
if (toclevel == Layout::NOT_IN_TOC)
|
|
|
|
continue;
|
2015-01-03 16:33:11 +00:00
|
|
|
|
|
|
|
DocumentClass const & tc = buf.params().documentClass();
|
2008-03-06 05:59:21 +00:00
|
|
|
DocumentClass::const_iterator lit = tc.begin();
|
|
|
|
DocumentClass::const_iterator len = tc.end();
|
2017-07-03 17:53:14 +00:00
|
|
|
int const newtoclevel =
|
2015-01-03 16:33:11 +00:00
|
|
|
(mode == OutlineIn ? toclevel + 1 : toclevel - 1);
|
|
|
|
LabelType const oldlabeltype = start->layout().labeltype;
|
|
|
|
|
2008-03-06 05:59:21 +00:00
|
|
|
for (; lit != len; ++lit) {
|
2015-01-03 16:33:11 +00:00
|
|
|
if (lit->toclevel == newtoclevel &&
|
|
|
|
lit->labeltype == oldlabeltype) {
|
2008-03-06 20:01:30 +00:00
|
|
|
start->setLayout(*lit);
|
2008-03-02 08:53:34 +00:00
|
|
|
break;
|
|
|
|
}
|
2007-11-06 17:13:43 +00:00
|
|
|
}
|
|
|
|
}
|
2009-05-09 15:49:09 +00:00
|
|
|
break;
|
2008-03-02 09:17:10 +00:00
|
|
|
}
|
2007-11-06 17:13:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-29 23:33:02 +00:00
|
|
|
void Text::number(Cursor & cur)
|
2003-11-10 09:06:48 +00:00
|
|
|
{
|
2007-10-28 18:51:54 +00:00
|
|
|
FontInfo font = ignore_font;
|
|
|
|
font.setNumber(FONT_TOGGLE);
|
2008-02-16 18:39:20 +00:00
|
|
|
toggleAndShow(cur, this, Font(font, ignore_language));
|
2003-11-10 09:06:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-08-09 15:29:34 +00:00
|
|
|
bool Text::isRTL(Paragraph const & par) const
|
2003-11-10 09:06:48 +00:00
|
|
|
{
|
2009-08-09 15:29:34 +00:00
|
|
|
Buffer const & buffer = owner_->buffer();
|
2007-09-04 10:27:55 +00:00
|
|
|
return par.isRTL(buffer.params());
|
2003-11-10 09:06:48 +00:00
|
|
|
}
|
|
|
|
|
2017-07-03 17:53:14 +00:00
|
|
|
|
2015-07-16 19:26:41 +00:00
|
|
|
namespace {
|
2017-07-03 17:53:14 +00:00
|
|
|
|
2015-07-16 19:26:41 +00:00
|
|
|
Language const * getLanguage(Cursor const & cur, string const & lang) {
|
|
|
|
return lang.empty() ? cur.getFont().language() : languages.getLanguage(lang);
|
|
|
|
}
|
|
|
|
|
2017-07-23 11:11:54 +00:00
|
|
|
} // namespace
|
2015-07-16 19:26:41 +00:00
|
|
|
|
2003-11-10 09:06:48 +00:00
|
|
|
|
2007-04-29 23:33:02 +00:00
|
|
|
void Text::dispatch(Cursor & cur, FuncRequest & cmd)
|
2002-08-20 13:00:25 +00:00
|
|
|
{
|
2007-11-15 20:04:51 +00:00
|
|
|
LYXERR(Debug::ACTION, "Text::dispatch: cmd: " << cmd);
|
2002-08-22 15:04:27 +00:00
|
|
|
|
2009-07-14 13:00:42 +00:00
|
|
|
// Dispatch if the cursor is inside the text. It is not the
|
|
|
|
// case for context menus (bug 5797).
|
|
|
|
if (cur.text() != this) {
|
|
|
|
cur.undispatched();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2008-02-22 12:22:28 +00:00
|
|
|
BufferView * bv = &cur.bv();
|
2009-05-14 12:35:04 +00:00
|
|
|
TextMetrics * tm = &bv->textMetrics(this);
|
|
|
|
if (!tm->contains(cur.pit())) {
|
2009-03-26 00:09:16 +00:00
|
|
|
lyx::dispatch(FuncRequest(LFUN_SCREEN_SHOW_CURSOR));
|
2009-05-14 12:35:04 +00:00
|
|
|
tm = &bv->textMetrics(this);
|
2009-02-03 23:18:41 +00:00
|
|
|
}
|
2008-02-22 12:22:28 +00:00
|
|
|
|
2006-11-17 17:42:52 +00:00
|
|
|
// FIXME: We use the update flag to indicates wether a singlePar or a
|
|
|
|
// full screen update is needed. We reset it here but shall we restore it
|
|
|
|
// at the end?
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.noScreenUpdate();
|
2006-11-17 17:42:52 +00:00
|
|
|
|
2013-04-27 21:52:55 +00:00
|
|
|
LBUFERR(this == cur.text());
|
2017-07-03 17:53:14 +00:00
|
|
|
|
2015-02-25 01:07:32 +00:00
|
|
|
// NOTE: This should NOT be a reference. See commit 94a5481a.
|
2015-02-25 01:04:10 +00:00
|
|
|
CursorSlice const oldTopSlice = cur.top();
|
2011-01-29 12:28:02 +00:00
|
|
|
bool const oldBoundary = cur.boundary();
|
|
|
|
bool const oldSelection = cur.selection();
|
2005-10-07 12:00:41 +00:00
|
|
|
// Signals that, even if needsUpdate == false, an update of the
|
|
|
|
// cursor paragraph is required
|
2010-04-09 19:00:42 +00:00
|
|
|
bool singleParUpdate = lyxaction.funcHasFlag(cmd.action(),
|
2005-10-07 12:00:41 +00:00
|
|
|
LyXAction::SingleParUpdate);
|
|
|
|
// Signals that a full-screen update is required
|
2010-04-09 19:00:42 +00:00
|
|
|
bool needsUpdate = !(lyxaction.funcHasFlag(cmd.action(),
|
2005-10-07 12:00:41 +00:00
|
|
|
LyXAction::NoUpdate) || singleParUpdate);
|
2011-01-29 12:28:02 +00:00
|
|
|
bool const last_misspelled = lyxrc.spellcheck_continuously
|
|
|
|
&& cur.paragraph().isMisspelled(cur.pos(), true);
|
2014-03-14 13:22:26 +00:00
|
|
|
|
2010-04-09 19:00:42 +00:00
|
|
|
FuncCode const act = cmd.action();
|
|
|
|
switch (act) {
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2006-04-26 22:43:26 +00:00
|
|
|
case LFUN_PARAGRAPH_MOVE_DOWN: {
|
|
|
|
pit_type const pit = cur.pit();
|
2015-03-12 14:57:29 +00:00
|
|
|
cur.recordUndo(pit, pit + 1);
|
2007-10-18 11:51:17 +00:00
|
|
|
cur.finishUndo();
|
2009-08-09 19:51:12 +00:00
|
|
|
pars_.swap(pit, pit + 1);
|
2006-04-26 22:43:26 +00:00
|
|
|
needsUpdate = true;
|
2010-07-09 14:37:00 +00:00
|
|
|
cur.forceBufferUpdate();
|
2007-07-13 16:12:44 +00:00
|
|
|
++cur.pit();
|
2006-04-26 22:43:26 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case LFUN_PARAGRAPH_MOVE_UP: {
|
|
|
|
pit_type const pit = cur.pit();
|
2015-03-12 14:57:29 +00:00
|
|
|
cur.recordUndo(pit - 1, pit);
|
2007-10-18 11:51:17 +00:00
|
|
|
cur.finishUndo();
|
2009-08-09 19:51:12 +00:00
|
|
|
pars_.swap(pit, pit - 1);
|
2007-07-13 16:12:44 +00:00
|
|
|
--cur.pit();
|
2006-04-26 22:43:26 +00:00
|
|
|
needsUpdate = true;
|
2010-07-09 14:37:00 +00:00
|
|
|
cur.forceBufferUpdate();
|
2006-04-26 22:43:26 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2002-08-20 13:00:25 +00:00
|
|
|
case LFUN_APPENDIX: {
|
2004-02-13 07:30:59 +00:00
|
|
|
Paragraph & par = cur.paragraph();
|
|
|
|
bool start = !par.params().startOfAppendix();
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2007-08-10 11:47:12 +00:00
|
|
|
// FIXME: The code below only makes sense at top level.
|
2005-02-25 11:55:36 +00:00
|
|
|
// Should LFUN_APPENDIX be restricted to top-level paragraphs?
|
2002-08-20 13:00:25 +00:00
|
|
|
// ensure that we have only one start_of_appendix in this document
|
2007-07-11 13:39:08 +00:00
|
|
|
// FIXME: this don't work for multipart document!
|
2004-11-24 21:53:46 +00:00
|
|
|
for (pit_type tmp = 0, end = pars_.size(); tmp != end; ++tmp) {
|
2004-03-25 09:16:36 +00:00
|
|
|
if (pars_[tmp].params().startOfAppendix()) {
|
2015-03-12 14:57:29 +00:00
|
|
|
cur.recordUndo(tmp, tmp);
|
2004-03-25 09:16:36 +00:00
|
|
|
pars_[tmp].params().startOfAppendix(false);
|
2002-10-30 21:02:40 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2007-10-18 11:51:17 +00:00
|
|
|
cur.recordUndo();
|
2004-02-13 07:30:59 +00:00
|
|
|
par.params().startOfAppendix(start);
|
2002-08-20 13:00:25 +00:00
|
|
|
|
|
|
|
// we can set the refreshing parameters now
|
2010-07-09 14:37:00 +00:00
|
|
|
cur.forceBufferUpdate();
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
2002-08-20 13:00:25 +00:00
|
|
|
}
|
|
|
|
|
2006-05-08 18:09:19 +00:00
|
|
|
case LFUN_WORD_DELETE_FORWARD:
|
2008-11-16 16:43:49 +00:00
|
|
|
if (cur.selection())
|
2007-07-10 12:20:00 +00:00
|
|
|
cutSelection(cur, true, false);
|
2008-11-16 16:43:49 +00:00
|
|
|
else
|
2017-02-18 18:12:55 +00:00
|
|
|
deleteWordForward(cur, cmd.getArg(0) == "force");
|
2004-03-08 21:14:45 +00:00
|
|
|
finishChange(cur, false);
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2006-05-08 18:09:19 +00:00
|
|
|
case LFUN_WORD_DELETE_BACKWARD:
|
2008-11-17 11:46:07 +00:00
|
|
|
if (cur.selection())
|
2007-07-10 12:20:00 +00:00
|
|
|
cutSelection(cur, true, false);
|
2008-11-17 11:46:07 +00:00
|
|
|
else
|
2017-02-18 18:12:55 +00:00
|
|
|
deleteWordBackward(cur, cmd.getArg(0) == "force");
|
2004-03-08 21:14:45 +00:00
|
|
|
finishChange(cur, false);
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2014-02-11 10:00:20 +00:00
|
|
|
case LFUN_LINE_DELETE_FORWARD:
|
2008-11-17 11:46:07 +00:00
|
|
|
if (cur.selection())
|
2007-07-10 12:20:00 +00:00
|
|
|
cutSelection(cur, true, false);
|
2008-11-17 11:46:07 +00:00
|
|
|
else
|
2009-05-14 12:35:04 +00:00
|
|
|
tm->deleteLineForward(cur);
|
2004-03-08 21:14:45 +00:00
|
|
|
finishChange(cur, false);
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_BUFFER_BEGIN:
|
2006-05-08 18:09:19 +00:00
|
|
|
case LFUN_BUFFER_BEGIN_SELECT:
|
2010-04-09 19:00:42 +00:00
|
|
|
needsUpdate |= cur.selHandle(act == LFUN_BUFFER_BEGIN_SELECT);
|
2008-11-17 11:46:07 +00:00
|
|
|
if (cur.depth() == 1)
|
2006-10-21 12:01:14 +00:00
|
|
|
needsUpdate |= cursorTop(cur);
|
2008-11-17 11:46:07 +00:00
|
|
|
else
|
2004-11-30 01:59:49 +00:00
|
|
|
cur.undispatched();
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.screenUpdateFlags(Update::FitCursor);
|
2004-11-30 01:59:49 +00:00
|
|
|
break;
|
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_BUFFER_END:
|
2006-05-08 18:09:19 +00:00
|
|
|
case LFUN_BUFFER_END_SELECT:
|
2010-04-09 19:00:42 +00:00
|
|
|
needsUpdate |= cur.selHandle(act == LFUN_BUFFER_END_SELECT);
|
2008-11-17 11:46:07 +00:00
|
|
|
if (cur.depth() == 1)
|
2006-10-21 12:01:14 +00:00
|
|
|
needsUpdate |= cursorBottom(cur);
|
2008-11-17 11:46:07 +00:00
|
|
|
else
|
2004-11-30 01:59:49 +00:00
|
|
|
cur.undispatched();
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.screenUpdateFlags(Update::FitCursor);
|
2004-11-30 01:59:49 +00:00
|
|
|
break;
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2009-03-16 13:33:27 +00:00
|
|
|
case LFUN_INSET_BEGIN:
|
|
|
|
case LFUN_INSET_BEGIN_SELECT:
|
2010-04-09 19:00:42 +00:00
|
|
|
needsUpdate |= cur.selHandle(act == LFUN_INSET_BEGIN_SELECT);
|
2009-08-22 14:34:50 +00:00
|
|
|
if (cur.depth() == 1 || !cur.top().at_begin())
|
2009-03-16 13:33:27 +00:00
|
|
|
needsUpdate |= cursorTop(cur);
|
|
|
|
else
|
|
|
|
cur.undispatched();
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.screenUpdateFlags(Update::FitCursor);
|
2009-03-16 13:33:27 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case LFUN_INSET_END:
|
|
|
|
case LFUN_INSET_END_SELECT:
|
2010-04-09 19:00:42 +00:00
|
|
|
needsUpdate |= cur.selHandle(act == LFUN_INSET_END_SELECT);
|
2009-08-22 14:34:50 +00:00
|
|
|
if (cur.depth() == 1 || !cur.top().at_end())
|
2009-03-16 13:33:27 +00:00
|
|
|
needsUpdate |= cursorBottom(cur);
|
|
|
|
else
|
|
|
|
cur.undispatched();
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.screenUpdateFlags(Update::FitCursor);
|
2009-03-16 13:33:27 +00:00
|
|
|
break;
|
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_CHAR_FORWARD:
|
2015-03-31 16:53:23 +00:00
|
|
|
case LFUN_CHAR_FORWARD_SELECT: {
|
2007-11-29 21:10:35 +00:00
|
|
|
//LYXERR0(" LFUN_CHAR_FORWARD[SEL]:\n" << cur);
|
2010-04-09 19:00:42 +00:00
|
|
|
needsUpdate |= cur.selHandle(act == LFUN_CHAR_FORWARD_SELECT);
|
2015-03-31 16:53:23 +00:00
|
|
|
bool const cur_moved = cursorForward(cur);
|
|
|
|
needsUpdate |= cur_moved;
|
2005-07-16 16:34:54 +00:00
|
|
|
|
2015-03-31 16:53:23 +00:00
|
|
|
if (!cur_moved && oldTopSlice == cur.top()
|
|
|
|
&& cur.boundary() == oldBoundary) {
|
2004-03-25 09:16:36 +00:00
|
|
|
cur.undispatched();
|
2007-10-22 22:18:52 +00:00
|
|
|
cmd = FuncRequest(LFUN_FINISHED_FORWARD);
|
2014-03-14 13:22:26 +00:00
|
|
|
|
2009-05-09 16:56:49 +00:00
|
|
|
// we will probably be moving out the inset, so we should execute
|
2014-03-14 13:22:26 +00:00
|
|
|
// the depm-mechanism, but only when the cursor has a place to
|
2009-05-09 16:56:49 +00:00
|
|
|
// go outside this inset, i.e. in a slice above.
|
2014-03-14 13:22:26 +00:00
|
|
|
if (cur.depth() > 1 && cur.pos() == cur.lastpos()
|
2009-05-09 16:56:49 +00:00
|
|
|
&& cur.pit() == cur.lastpit()) {
|
2014-03-14 13:22:26 +00:00
|
|
|
// The cursor hasn't changed yet. To give the
|
2009-05-09 16:56:49 +00:00
|
|
|
// DEPM the possibility of doing something we must
|
|
|
|
// provide it with two different cursors.
|
|
|
|
Cursor dummy = cur;
|
|
|
|
dummy.pos() = dummy.pit() = 0;
|
2013-05-19 12:42:27 +00:00
|
|
|
if (cur.bv().checkDepm(dummy, cur))
|
2010-12-20 12:01:12 +00:00
|
|
|
cur.forceBufferUpdate();
|
2009-05-09 16:56:49 +00:00
|
|
|
}
|
2007-09-21 20:57:00 +00:00
|
|
|
}
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
2015-03-31 16:53:23 +00:00
|
|
|
}
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_CHAR_BACKWARD:
|
2015-03-31 16:53:23 +00:00
|
|
|
case LFUN_CHAR_BACKWARD_SELECT: {
|
2006-05-08 18:09:19 +00:00
|
|
|
//lyxerr << "handle LFUN_CHAR_BACKWARD[_SELECT]:\n" << cur << endl;
|
2010-04-09 19:00:42 +00:00
|
|
|
needsUpdate |= cur.selHandle(act == LFUN_CHAR_BACKWARD_SELECT);
|
2015-03-31 16:53:23 +00:00
|
|
|
bool const cur_moved = cursorBackward(cur);
|
|
|
|
needsUpdate |= cur_moved;
|
2005-07-17 10:31:44 +00:00
|
|
|
|
2015-03-31 16:53:23 +00:00
|
|
|
if (!cur_moved && oldTopSlice == cur.top()
|
|
|
|
&& cur.boundary() == oldBoundary) {
|
2004-03-25 09:16:36 +00:00
|
|
|
cur.undispatched();
|
2007-10-22 22:18:52 +00:00
|
|
|
cmd = FuncRequest(LFUN_FINISHED_BACKWARD);
|
2009-05-09 16:56:49 +00:00
|
|
|
|
|
|
|
// we will probably be moving out the inset, so we should execute
|
2014-03-14 13:22:26 +00:00
|
|
|
// the depm-mechanism, but only when the cursor has a place to
|
2009-05-09 16:56:49 +00:00
|
|
|
// go outside this inset, i.e. in a slice above.
|
|
|
|
if (cur.depth() > 1 && cur.pos() == 0 && cur.pit() == 0) {
|
2014-03-14 13:22:26 +00:00
|
|
|
// The cursor hasn't changed yet. To give the
|
2009-05-09 16:56:49 +00:00
|
|
|
// DEPM the possibility of doing something we must
|
|
|
|
// provide it with two different cursors.
|
|
|
|
Cursor dummy = cur;
|
|
|
|
dummy.pos() = cur.lastpos();
|
|
|
|
dummy.pit() = cur.lastpit();
|
2013-05-19 12:42:27 +00:00
|
|
|
if (cur.bv().checkDepm(dummy, cur))
|
2010-07-09 14:37:00 +00:00
|
|
|
cur.forceBufferUpdate();
|
2009-05-09 16:56:49 +00:00
|
|
|
}
|
2007-10-22 22:18:52 +00:00
|
|
|
}
|
|
|
|
break;
|
2015-03-31 16:53:23 +00:00
|
|
|
}
|
2007-10-22 22:18:52 +00:00
|
|
|
|
|
|
|
case LFUN_CHAR_LEFT:
|
|
|
|
case LFUN_CHAR_LEFT_SELECT:
|
2008-02-10 19:52:45 +00:00
|
|
|
if (lyxrc.visual_cursor) {
|
2010-04-09 19:00:42 +00:00
|
|
|
needsUpdate |= cur.selHandle(act == LFUN_CHAR_LEFT_SELECT);
|
2015-03-31 16:53:23 +00:00
|
|
|
bool const cur_moved = cursorVisLeft(cur);
|
|
|
|
needsUpdate |= cur_moved;
|
|
|
|
if (!cur_moved && oldTopSlice == cur.top()
|
|
|
|
&& cur.boundary() == oldBoundary) {
|
2008-02-10 19:52:45 +00:00
|
|
|
cur.undispatched();
|
|
|
|
cmd = FuncRequest(LFUN_FINISHED_LEFT);
|
|
|
|
}
|
2007-10-22 22:18:52 +00:00
|
|
|
} else {
|
2015-07-16 09:55:45 +00:00
|
|
|
if (cur.reverseDirectionNeeded()) {
|
2010-04-09 19:00:42 +00:00
|
|
|
cmd.setAction(cmd.action() == LFUN_CHAR_LEFT_SELECT ?
|
|
|
|
LFUN_CHAR_FORWARD_SELECT : LFUN_CHAR_FORWARD);
|
2008-02-10 19:52:45 +00:00
|
|
|
} else {
|
2010-04-09 19:00:42 +00:00
|
|
|
cmd.setAction(cmd.action() == LFUN_CHAR_LEFT_SELECT ?
|
|
|
|
LFUN_CHAR_BACKWARD_SELECT : LFUN_CHAR_BACKWARD);
|
2008-02-10 19:52:45 +00:00
|
|
|
}
|
|
|
|
dispatch(cur, cmd);
|
|
|
|
return;
|
2007-10-22 22:18:52 +00:00
|
|
|
}
|
2008-02-10 19:52:45 +00:00
|
|
|
break;
|
2007-10-22 22:18:52 +00:00
|
|
|
|
|
|
|
case LFUN_CHAR_RIGHT:
|
|
|
|
case LFUN_CHAR_RIGHT_SELECT:
|
2008-02-10 19:52:45 +00:00
|
|
|
if (lyxrc.visual_cursor) {
|
2010-04-09 19:00:42 +00:00
|
|
|
needsUpdate |= cur.selHandle(cmd.action() == LFUN_CHAR_RIGHT_SELECT);
|
2015-03-31 16:53:23 +00:00
|
|
|
bool const cur_moved = cursorVisRight(cur);
|
|
|
|
needsUpdate |= cur_moved;
|
|
|
|
if (!cur_moved && oldTopSlice == cur.top()
|
|
|
|
&& cur.boundary() == oldBoundary) {
|
2008-02-10 19:52:45 +00:00
|
|
|
cur.undispatched();
|
|
|
|
cmd = FuncRequest(LFUN_FINISHED_RIGHT);
|
|
|
|
}
|
2007-10-22 22:18:52 +00:00
|
|
|
} else {
|
2015-07-16 09:55:45 +00:00
|
|
|
if (cur.reverseDirectionNeeded()) {
|
2010-04-09 19:00:42 +00:00
|
|
|
cmd.setAction(cmd.action() == LFUN_CHAR_RIGHT_SELECT ?
|
|
|
|
LFUN_CHAR_BACKWARD_SELECT : LFUN_CHAR_BACKWARD);
|
2008-02-10 19:52:45 +00:00
|
|
|
} else {
|
2010-04-09 19:00:42 +00:00
|
|
|
cmd.setAction(cmd.action() == LFUN_CHAR_RIGHT_SELECT ?
|
|
|
|
LFUN_CHAR_FORWARD_SELECT : LFUN_CHAR_FORWARD);
|
2008-02-10 19:52:45 +00:00
|
|
|
}
|
|
|
|
dispatch(cur, cmd);
|
|
|
|
return;
|
2007-09-21 20:57:00 +00:00
|
|
|
}
|
2008-02-10 19:52:45 +00:00
|
|
|
break;
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2007-06-14 20:32:28 +00:00
|
|
|
case LFUN_UP_SELECT:
|
|
|
|
case LFUN_DOWN_SELECT:
|
2004-02-20 17:19:53 +00:00
|
|
|
case LFUN_UP:
|
2007-06-14 20:32:28 +00:00
|
|
|
case LFUN_DOWN: {
|
2007-06-15 05:31:11 +00:00
|
|
|
// stop/start the selection
|
2010-04-09 19:00:42 +00:00
|
|
|
bool select = cmd.action() == LFUN_DOWN_SELECT ||
|
|
|
|
cmd.action() == LFUN_UP_SELECT;
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2007-06-14 20:32:28 +00:00
|
|
|
// move cursor up/down
|
2010-04-09 19:00:42 +00:00
|
|
|
bool up = cmd.action() == LFUN_UP_SELECT || cmd.action() == LFUN_UP;
|
2008-11-16 18:03:52 +00:00
|
|
|
bool const atFirstOrLastRow = cur.atFirstOrLastRow(up);
|
|
|
|
|
|
|
|
if (!atFirstOrLastRow) {
|
2014-03-14 13:22:26 +00:00
|
|
|
needsUpdate |= cur.selHandle(select);
|
2008-11-16 18:03:52 +00:00
|
|
|
cur.upDownInText(up, needsUpdate);
|
2007-06-14 20:32:28 +00:00
|
|
|
needsUpdate |= cur.beforeDispatchCursor().inMathed();
|
2008-11-16 18:03:52 +00:00
|
|
|
} else {
|
|
|
|
// if the cursor cannot be moved up or down do not remove
|
|
|
|
// the selection right now, but wait for the next dispatch.
|
|
|
|
if (select)
|
2014-03-14 13:22:26 +00:00
|
|
|
needsUpdate |= cur.selHandle(select);
|
2008-11-16 18:03:52 +00:00
|
|
|
cur.upDownInText(up, needsUpdate);
|
2004-03-25 09:16:36 +00:00
|
|
|
cur.undispatched();
|
2008-11-16 18:03:52 +00:00
|
|
|
}
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
2007-05-30 19:38:22 +00:00
|
|
|
}
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_PARAGRAPH_UP:
|
2006-05-08 18:09:19 +00:00
|
|
|
case LFUN_PARAGRAPH_UP_SELECT:
|
2010-04-09 19:00:42 +00:00
|
|
|
needsUpdate |= cur.selHandle(cmd.action() == LFUN_PARAGRAPH_UP_SELECT);
|
2006-10-21 12:01:14 +00:00
|
|
|
needsUpdate |= cursorUpParagraph(cur);
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_PARAGRAPH_DOWN:
|
2006-05-08 18:09:19 +00:00
|
|
|
case LFUN_PARAGRAPH_DOWN_SELECT:
|
2010-04-09 19:00:42 +00:00
|
|
|
needsUpdate |= cur.selHandle(cmd.action() == LFUN_PARAGRAPH_DOWN_SELECT);
|
2006-10-21 12:01:14 +00:00
|
|
|
needsUpdate |= cursorDownParagraph(cur);
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2006-07-13 07:43:48 +00:00
|
|
|
case LFUN_LINE_BEGIN:
|
2006-05-08 18:09:19 +00:00
|
|
|
case LFUN_LINE_BEGIN_SELECT:
|
2010-04-09 19:00:42 +00:00
|
|
|
needsUpdate |= cur.selHandle(cmd.action() == LFUN_LINE_BEGIN_SELECT);
|
2009-05-14 12:35:04 +00:00
|
|
|
needsUpdate |= tm->cursorHome(cur);
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2006-07-13 07:43:48 +00:00
|
|
|
case LFUN_LINE_END:
|
2006-05-08 18:09:19 +00:00
|
|
|
case LFUN_LINE_END_SELECT:
|
2010-04-09 19:00:42 +00:00
|
|
|
needsUpdate |= cur.selHandle(cmd.action() == LFUN_LINE_END_SELECT);
|
2009-05-14 12:35:04 +00:00
|
|
|
needsUpdate |= tm->cursorEnd(cur);
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2009-05-03 18:58:00 +00:00
|
|
|
case LFUN_SECTION_SELECT: {
|
2009-05-03 19:02:03 +00:00
|
|
|
Buffer const & buf = *cur.buffer();
|
|
|
|
pit_type const pit = cur.pit();
|
2009-05-03 18:58:00 +00:00
|
|
|
ParagraphList & pars = buf.text().paragraphs();
|
|
|
|
ParagraphList::iterator bgn = pars.begin();
|
|
|
|
// The first paragraph of the area to be selected:
|
2016-01-10 16:59:42 +00:00
|
|
|
ParagraphList::iterator start = lyx::next(bgn, pit);
|
2009-05-03 18:58:00 +00:00
|
|
|
// The final paragraph of area to be selected:
|
|
|
|
ParagraphList::iterator finish = start;
|
|
|
|
ParagraphList::iterator end = pars.end();
|
|
|
|
|
2012-12-15 15:47:57 +00:00
|
|
|
int const thistoclevel = buf.text().getTocLevel(distance(bgn, start));
|
2009-05-03 18:58:00 +00:00
|
|
|
if (thistoclevel == Layout::NOT_IN_TOC)
|
|
|
|
break;
|
|
|
|
|
2009-05-03 23:32:16 +00:00
|
|
|
cur.pos() = 0;
|
|
|
|
Cursor const old_cur = cur;
|
|
|
|
needsUpdate |= cur.selHandle(true);
|
|
|
|
|
2009-05-03 18:58:00 +00:00
|
|
|
// Move out (down) from this section header
|
|
|
|
if (finish != end)
|
|
|
|
++finish;
|
|
|
|
|
|
|
|
// Seek the one (on same level) below
|
2009-05-03 23:32:16 +00:00
|
|
|
for (; finish != end; ++finish, ++cur.pit()) {
|
2012-12-15 15:47:57 +00:00
|
|
|
int const toclevel = buf.text().getTocLevel(distance(bgn, finish));
|
2009-05-03 18:58:00 +00:00
|
|
|
if (toclevel != Layout::NOT_IN_TOC && toclevel <= thistoclevel)
|
|
|
|
break;
|
|
|
|
}
|
2009-05-03 23:32:16 +00:00
|
|
|
cur.pos() = cur.lastpos();
|
2017-10-11 09:56:09 +00:00
|
|
|
cur.boundary(false);
|
|
|
|
cur.setCurrentFont();
|
2014-03-14 13:22:26 +00:00
|
|
|
|
2009-05-03 18:58:00 +00:00
|
|
|
needsUpdate |= cur != old_cur;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2007-10-28 20:35:57 +00:00
|
|
|
case LFUN_WORD_RIGHT:
|
|
|
|
case LFUN_WORD_RIGHT_SELECT:
|
2008-05-04 20:22:19 +00:00
|
|
|
if (lyxrc.visual_cursor) {
|
2010-04-09 19:00:42 +00:00
|
|
|
needsUpdate |= cur.selHandle(cmd.action() == LFUN_WORD_RIGHT_SELECT);
|
2015-03-31 16:53:23 +00:00
|
|
|
bool const cur_moved = cursorVisRightOneWord(cur);
|
|
|
|
needsUpdate |= cur_moved;
|
|
|
|
if (!cur_moved && oldTopSlice == cur.top()
|
|
|
|
&& cur.boundary() == oldBoundary) {
|
2008-05-04 20:22:19 +00:00
|
|
|
cur.undispatched();
|
|
|
|
cmd = FuncRequest(LFUN_FINISHED_RIGHT);
|
|
|
|
}
|
2007-10-28 20:35:57 +00:00
|
|
|
} else {
|
2015-07-16 09:55:45 +00:00
|
|
|
if (cur.reverseDirectionNeeded()) {
|
2010-04-09 19:00:42 +00:00
|
|
|
cmd.setAction(cmd.action() == LFUN_WORD_RIGHT_SELECT ?
|
|
|
|
LFUN_WORD_BACKWARD_SELECT : LFUN_WORD_BACKWARD);
|
2008-05-04 20:22:19 +00:00
|
|
|
} else {
|
2010-04-09 19:00:42 +00:00
|
|
|
cmd.setAction(cmd.action() == LFUN_WORD_RIGHT_SELECT ?
|
|
|
|
LFUN_WORD_FORWARD_SELECT : LFUN_WORD_FORWARD);
|
2008-05-04 20:22:19 +00:00
|
|
|
}
|
|
|
|
dispatch(cur, cmd);
|
|
|
|
return;
|
2007-10-28 20:35:57 +00:00
|
|
|
}
|
2008-05-04 20:22:19 +00:00
|
|
|
break;
|
2007-10-28 20:35:57 +00:00
|
|
|
|
2006-07-13 07:43:48 +00:00
|
|
|
case LFUN_WORD_FORWARD:
|
2015-03-31 16:53:23 +00:00
|
|
|
case LFUN_WORD_FORWARD_SELECT: {
|
2010-04-09 19:00:42 +00:00
|
|
|
needsUpdate |= cur.selHandle(cmd.action() == LFUN_WORD_FORWARD_SELECT);
|
2015-03-31 16:53:23 +00:00
|
|
|
bool const cur_moved = cursorForwardOneWord(cur);
|
|
|
|
needsUpdate |= cur_moved;
|
2010-10-25 01:18:48 +00:00
|
|
|
|
2015-03-31 16:53:23 +00:00
|
|
|
if (!cur_moved && oldTopSlice == cur.top()
|
|
|
|
&& cur.boundary() == oldBoundary) {
|
2010-10-25 01:18:48 +00:00
|
|
|
cur.undispatched();
|
|
|
|
cmd = FuncRequest(LFUN_FINISHED_FORWARD);
|
2014-03-14 13:22:26 +00:00
|
|
|
|
2010-10-25 01:18:48 +00:00
|
|
|
// we will probably be moving out the inset, so we should execute
|
2014-03-14 13:22:26 +00:00
|
|
|
// the depm-mechanism, but only when the cursor has a place to
|
2010-10-25 01:18:48 +00:00
|
|
|
// go outside this inset, i.e. in a slice above.
|
2014-03-14 13:22:26 +00:00
|
|
|
if (cur.depth() > 1 && cur.pos() == cur.lastpos()
|
2010-10-25 01:18:48 +00:00
|
|
|
&& cur.pit() == cur.lastpit()) {
|
2014-03-14 13:22:26 +00:00
|
|
|
// The cursor hasn't changed yet. To give the
|
2010-10-25 01:18:48 +00:00
|
|
|
// DEPM the possibility of doing something we must
|
|
|
|
// provide it with two different cursors.
|
|
|
|
Cursor dummy = cur;
|
|
|
|
dummy.pos() = dummy.pit() = 0;
|
2013-05-19 12:42:27 +00:00
|
|
|
if (cur.bv().checkDepm(dummy, cur))
|
2010-12-29 21:34:33 +00:00
|
|
|
cur.forceBufferUpdate();
|
2010-10-25 01:18:48 +00:00
|
|
|
}
|
|
|
|
}
|
2007-10-28 20:35:57 +00:00
|
|
|
break;
|
2015-03-31 16:53:23 +00:00
|
|
|
}
|
2007-10-28 20:35:57 +00:00
|
|
|
|
|
|
|
case LFUN_WORD_LEFT:
|
|
|
|
case LFUN_WORD_LEFT_SELECT:
|
2008-05-04 20:22:19 +00:00
|
|
|
if (lyxrc.visual_cursor) {
|
2010-04-09 19:00:42 +00:00
|
|
|
needsUpdate |= cur.selHandle(cmd.action() == LFUN_WORD_LEFT_SELECT);
|
2015-03-31 16:53:23 +00:00
|
|
|
bool const cur_moved = cursorVisLeftOneWord(cur);
|
|
|
|
needsUpdate |= cur_moved;
|
|
|
|
if (!cur_moved && oldTopSlice == cur.top()
|
|
|
|
&& cur.boundary() == oldBoundary) {
|
2008-05-04 20:22:19 +00:00
|
|
|
cur.undispatched();
|
|
|
|
cmd = FuncRequest(LFUN_FINISHED_LEFT);
|
|
|
|
}
|
2007-10-28 20:35:57 +00:00
|
|
|
} else {
|
2015-07-16 09:55:45 +00:00
|
|
|
if (cur.reverseDirectionNeeded()) {
|
2010-04-09 19:00:42 +00:00
|
|
|
cmd.setAction(cmd.action() == LFUN_WORD_LEFT_SELECT ?
|
|
|
|
LFUN_WORD_FORWARD_SELECT : LFUN_WORD_FORWARD);
|
2008-05-04 20:22:19 +00:00
|
|
|
} else {
|
2010-04-09 19:00:42 +00:00
|
|
|
cmd.setAction(cmd.action() == LFUN_WORD_LEFT_SELECT ?
|
|
|
|
LFUN_WORD_BACKWARD_SELECT : LFUN_WORD_BACKWARD);
|
2008-05-04 20:22:19 +00:00
|
|
|
}
|
|
|
|
dispatch(cur, cmd);
|
|
|
|
return;
|
2007-10-28 20:35:57 +00:00
|
|
|
}
|
2008-05-04 20:22:19 +00:00
|
|
|
break;
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2006-07-13 07:43:48 +00:00
|
|
|
case LFUN_WORD_BACKWARD:
|
2015-03-31 16:53:23 +00:00
|
|
|
case LFUN_WORD_BACKWARD_SELECT: {
|
2010-04-09 19:00:42 +00:00
|
|
|
needsUpdate |= cur.selHandle(cmd.action() == LFUN_WORD_BACKWARD_SELECT);
|
2015-03-31 16:53:23 +00:00
|
|
|
bool const cur_moved = cursorBackwardOneWord(cur);
|
|
|
|
needsUpdate |= cur_moved;
|
2014-03-14 13:22:26 +00:00
|
|
|
|
2015-03-31 16:53:23 +00:00
|
|
|
if (!cur_moved && oldTopSlice == cur.top()
|
|
|
|
&& cur.boundary() == oldBoundary) {
|
2010-10-25 01:18:48 +00:00
|
|
|
cur.undispatched();
|
|
|
|
cmd = FuncRequest(LFUN_FINISHED_BACKWARD);
|
2014-03-14 13:22:26 +00:00
|
|
|
|
2010-10-25 01:18:48 +00:00
|
|
|
// we will probably be moving out the inset, so we should execute
|
2014-03-14 13:22:26 +00:00
|
|
|
// the depm-mechanism, but only when the cursor has a place to
|
2010-10-25 01:18:48 +00:00
|
|
|
// go outside this inset, i.e. in a slice above.
|
2014-03-14 13:22:26 +00:00
|
|
|
if (cur.depth() > 1 && cur.pos() == 0
|
2010-10-25 01:18:48 +00:00
|
|
|
&& cur.pit() == 0) {
|
2014-03-14 13:22:26 +00:00
|
|
|
// The cursor hasn't changed yet. To give the
|
2010-10-25 01:18:48 +00:00
|
|
|
// DEPM the possibility of doing something we must
|
|
|
|
// provide it with two different cursors.
|
|
|
|
Cursor dummy = cur;
|
|
|
|
dummy.pos() = cur.lastpos();
|
|
|
|
dummy.pit() = cur.lastpit();
|
2013-05-19 12:42:27 +00:00
|
|
|
if (cur.bv().checkDepm(dummy, cur))
|
2010-10-25 01:18:48 +00:00
|
|
|
cur.forceBufferUpdate();
|
|
|
|
}
|
|
|
|
}
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
2015-03-31 16:53:23 +00:00
|
|
|
}
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_WORD_SELECT: {
|
2006-10-21 00:16:43 +00:00
|
|
|
selectWord(cur, WHOLE_WORD);
|
2004-02-06 13:59:26 +00:00
|
|
|
finishChange(cur, true);
|
2002-09-11 14:48:19 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2008-03-26 08:10:01 +00:00
|
|
|
case LFUN_NEWLINE_INSERT: {
|
|
|
|
InsetNewlineParams inp;
|
|
|
|
docstring arg = cmd.argument();
|
|
|
|
if (arg == "linebreak")
|
|
|
|
inp.kind = InsetNewlineParams::LINEBREAK;
|
|
|
|
else
|
|
|
|
inp.kind = InsetNewlineParams::NEWLINE;
|
2013-01-21 13:49:45 +00:00
|
|
|
cap::replaceSelection(cur);
|
|
|
|
cur.recordUndo();
|
2008-03-26 08:10:01 +00:00
|
|
|
cur.insert(new InsetNewline(inp));
|
|
|
|
cur.posForward();
|
|
|
|
moveCursor(cur, false);
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
2003-03-12 19:16:42 +00:00
|
|
|
}
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2009-07-14 14:52:11 +00:00
|
|
|
case LFUN_TAB_INSERT: {
|
|
|
|
bool const multi_par_selection = cur.selection() &&
|
|
|
|
cur.selBegin().pit() != cur.selEnd().pit();
|
|
|
|
if (multi_par_selection) {
|
|
|
|
// If there is a multi-paragraph selection, a tab is inserted
|
|
|
|
// at the beginning of each paragraph.
|
|
|
|
cur.recordUndoSelection();
|
|
|
|
pit_type const pit_end = cur.selEnd().pit();
|
|
|
|
for (pit_type pit = cur.selBegin().pit(); pit <= pit_end; pit++) {
|
2014-03-14 13:22:26 +00:00
|
|
|
pars_[pit].insertChar(0, '\t',
|
2014-03-29 22:52:36 +00:00
|
|
|
bv->buffer().params().track_changes);
|
2009-07-14 14:52:11 +00:00
|
|
|
// Update the selection pos to make sure the selection does not
|
|
|
|
// change as the inserted tab will increase the logical pos.
|
2010-04-15 18:16:07 +00:00
|
|
|
if (cur.realAnchor().pit() == pit)
|
|
|
|
cur.realAnchor().forwardPos();
|
2009-07-14 14:52:11 +00:00
|
|
|
if (cur.pit() == pit)
|
|
|
|
cur.forwardPos();
|
|
|
|
}
|
|
|
|
cur.finishUndo();
|
|
|
|
} else {
|
|
|
|
// Maybe we shouldn't allow tabs within a line, because they
|
|
|
|
// are not (yet) aligned as one might do expect.
|
|
|
|
FuncRequest cmd(LFUN_SELF_INSERT, from_ascii("\t"));
|
2014-03-14 13:22:26 +00:00
|
|
|
dispatch(cur, cmd);
|
2009-07-14 14:52:11 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case LFUN_TAB_DELETE: {
|
2014-03-29 22:52:36 +00:00
|
|
|
bool const tc = bv->buffer().params().track_changes;
|
2009-07-14 14:52:11 +00:00
|
|
|
if (cur.selection()) {
|
|
|
|
// If there is a selection, a tab (if present) is removed from
|
|
|
|
// the beginning of each paragraph.
|
|
|
|
cur.recordUndoSelection();
|
|
|
|
pit_type const pit_end = cur.selEnd().pit();
|
|
|
|
for (pit_type pit = cur.selBegin().pit(); pit <= pit_end; pit++) {
|
|
|
|
Paragraph & par = paragraphs()[pit];
|
2010-10-18 10:48:29 +00:00
|
|
|
if (par.empty())
|
|
|
|
continue;
|
|
|
|
char_type const c = par.getChar(0);
|
|
|
|
if (c == '\t' || c == ' ') {
|
|
|
|
// remove either 1 tab or 4 spaces.
|
|
|
|
int const n = (c == ' ' ? 4 : 1);
|
2014-03-14 13:22:26 +00:00
|
|
|
for (int i = 0; i < n
|
2010-10-18 10:48:29 +00:00
|
|
|
&& !par.empty() && par.getChar(0) == c; ++i) {
|
2009-07-14 14:52:11 +00:00
|
|
|
if (cur.pit() == pit)
|
|
|
|
cur.posBackward();
|
2014-03-14 13:22:26 +00:00
|
|
|
if (cur.realAnchor().pit() == pit
|
2010-10-18 10:48:29 +00:00
|
|
|
&& cur.realAnchor().pos() > 0 )
|
2010-04-15 18:16:07 +00:00
|
|
|
cur.realAnchor().backwardPos();
|
2009-07-14 14:52:11 +00:00
|
|
|
par.eraseChar(0, tc);
|
|
|
|
}
|
2010-10-18 10:48:29 +00:00
|
|
|
}
|
2009-07-14 14:52:11 +00:00
|
|
|
}
|
|
|
|
cur.finishUndo();
|
|
|
|
} else {
|
2014-03-14 13:22:26 +00:00
|
|
|
// If there is no selection, try to remove a tab or some spaces
|
2009-07-14 14:52:11 +00:00
|
|
|
// before the position of the cursor.
|
|
|
|
Paragraph & par = paragraphs()[cur.pit()];
|
|
|
|
pos_type const pos = cur.pos();
|
2014-03-14 13:22:26 +00:00
|
|
|
|
2009-07-14 14:52:11 +00:00
|
|
|
if (pos == 0)
|
|
|
|
break;
|
2014-03-14 13:22:26 +00:00
|
|
|
|
2009-07-14 14:52:11 +00:00
|
|
|
char_type const c = par.getChar(pos - 1);
|
|
|
|
cur.recordUndo();
|
|
|
|
if (c == '\t') {
|
|
|
|
cur.posBackward();
|
|
|
|
par.eraseChar(cur.pos(), tc);
|
|
|
|
} else
|
2014-03-14 13:22:26 +00:00
|
|
|
for (int n_spaces = 0;
|
2009-07-14 14:52:11 +00:00
|
|
|
cur.pos() > 0
|
2014-03-14 13:22:26 +00:00
|
|
|
&& par.getChar(cur.pos() - 1) == ' '
|
2009-07-14 14:52:11 +00:00
|
|
|
&& n_spaces < 4;
|
|
|
|
++n_spaces) {
|
|
|
|
cur.posBackward();
|
|
|
|
par.eraseChar(cur.pos(), tc);
|
|
|
|
}
|
|
|
|
cur.finishUndo();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-05-08 18:09:19 +00:00
|
|
|
case LFUN_CHAR_DELETE_FORWARD:
|
2004-01-20 14:25:24 +00:00
|
|
|
if (!cur.selection()) {
|
2006-03-10 16:10:35 +00:00
|
|
|
if (cur.pos() == cur.paragraph().size())
|
|
|
|
// Par boundary, force full-screen update
|
|
|
|
singleParUpdate = false;
|
2017-02-18 18:12:55 +00:00
|
|
|
else if (cmd.getArg(0) != "force" && cur.confirmDeletion()) {
|
|
|
|
cur.resetAnchor();
|
|
|
|
cur.selection(true);
|
|
|
|
cur.posForward();
|
|
|
|
cur.setSelection();
|
|
|
|
break;
|
|
|
|
}
|
2006-10-21 12:01:14 +00:00
|
|
|
needsUpdate |= erase(cur);
|
2004-01-20 14:25:24 +00:00
|
|
|
cur.resetAnchor();
|
2002-08-20 15:26:52 +00:00
|
|
|
} else {
|
2004-02-13 11:05:29 +00:00
|
|
|
cutSelection(cur, true, false);
|
2006-03-10 16:10:35 +00:00
|
|
|
singleParUpdate = false;
|
2002-08-20 15:26:52 +00:00
|
|
|
}
|
2004-01-20 14:25:24 +00:00
|
|
|
moveCursor(cur, false);
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
|
|
|
|
2006-05-08 18:09:19 +00:00
|
|
|
case LFUN_CHAR_DELETE_BACKWARD:
|
2004-01-20 14:25:24 +00:00
|
|
|
if (!cur.selection()) {
|
2006-09-17 10:03:00 +00:00
|
|
|
if (bv->getIntl().getTransManager().backspace()) {
|
2015-06-07 22:38:10 +00:00
|
|
|
bool par_boundary = cur.pos() == 0;
|
2015-06-07 22:41:36 +00:00
|
|
|
bool first_par = cur.pit() == 0;
|
2006-03-10 16:10:35 +00:00
|
|
|
// Par boundary, full-screen update
|
2015-06-07 22:38:10 +00:00
|
|
|
if (par_boundary)
|
2006-03-10 16:10:35 +00:00
|
|
|
singleParUpdate = false;
|
2017-02-18 18:12:55 +00:00
|
|
|
else if (cmd.getArg(0) != "force" && cur.confirmDeletion(true)) {
|
|
|
|
cur.resetAnchor();
|
|
|
|
cur.selection(true);
|
|
|
|
cur.posBackward();
|
|
|
|
cur.setSelection();
|
|
|
|
break;
|
|
|
|
}
|
2006-10-21 12:01:14 +00:00
|
|
|
needsUpdate |= backspace(cur);
|
2004-01-20 14:25:24 +00:00
|
|
|
cur.resetAnchor();
|
2015-06-07 22:41:36 +00:00
|
|
|
if (par_boundary && !first_par && cur.pos() > 0
|
2015-06-07 22:38:10 +00:00
|
|
|
&& cur.paragraph().isEnvSeparator(cur.pos() - 1)) {
|
|
|
|
needsUpdate |= backspace(cur);
|
|
|
|
cur.resetAnchor();
|
|
|
|
}
|
2002-08-20 15:26:52 +00:00
|
|
|
}
|
2002-08-26 13:25:49 +00:00
|
|
|
} else {
|
2004-02-13 11:05:29 +00:00
|
|
|
cutSelection(cur, true, false);
|
2006-03-10 16:10:35 +00:00
|
|
|
singleParUpdate = false;
|
2002-08-26 13:25:49 +00:00
|
|
|
}
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
|
|
|
|
Fix bugs #8546 and #9055, and introduce new separator inset.
The algorithm used for breaking a paragraph in LaTeX export is changed
for avoiding spurious blank lines causing too much vertical space.
This change is tied to the introduction of a new inset (with two
different specializations) helping in either outputing LaTeX paragraph
breaks or separating environments in LyX. Both of the above goals were
previously achieved by the ---Separator--- layout and can now be
accomplished by the new inset in a more natural way. As an example,
after leaving an environment by hitting the Return key for two times,
a third return automatically inserts a parbreak inset, which is
equivalent to the old separator layout, i.e., it also introduces a
blank line in the output. If this blank line is not wanted, the
parbreak separator can be changed to a plain separator by a right
click of the mouse. Of course, an environment can still be separated
by the following one by using the Alt+P+Return shortcut (or the
corresponding menu key), but now the plain separator inset is used
instead of the old separator layout, such that no blank line occurs in
the LaTeX output.
Old documents are converted such that the LaTeX output remains unchanged.
As a result of this conversion, the old separator layout is replaced by
the new parbreak inset, which may also appear in places where the old
algorithm was introducing blank lines while the new one is not.
Note that not all blank lines were actually affecting the LaTeX output,
because a blank line is simply ignored by the TeX engine when it occurs
in the so called "vertical mode" (e.g., after an alignment environment).
The old ---Separator--- layout is now gone and old layout files using it
are also automatically converted.
Round trip conversions between old and new format should leave a document
unchanged. This means that the new behavior about paragraph breaking is
not "carried back" to the old format. Indeed, this would need introducing
special LaTeX commands in ERT that would accumulate in roundtrip
conversions, horribly cluttering the document. So, when converting a
modified document to old formats, the LaTeX output may slightly differ in
vertical spacing if the document is processed by an old version of LyX.
In other words, forward compatibility is guaranteed, but not backwards.
2014-05-10 21:25:11 +00:00
|
|
|
case LFUN_PARAGRAPH_BREAK: {
|
2006-10-21 00:16:43 +00:00
|
|
|
cap::replaceSelection(cur);
|
Fix bugs #8546 and #9055, and introduce new separator inset.
The algorithm used for breaking a paragraph in LaTeX export is changed
for avoiding spurious blank lines causing too much vertical space.
This change is tied to the introduction of a new inset (with two
different specializations) helping in either outputing LaTeX paragraph
breaks or separating environments in LyX. Both of the above goals were
previously achieved by the ---Separator--- layout and can now be
accomplished by the new inset in a more natural way. As an example,
after leaving an environment by hitting the Return key for two times,
a third return automatically inserts a parbreak inset, which is
equivalent to the old separator layout, i.e., it also introduces a
blank line in the output. If this blank line is not wanted, the
parbreak separator can be changed to a plain separator by a right
click of the mouse. Of course, an environment can still be separated
by the following one by using the Alt+P+Return shortcut (or the
corresponding menu key), but now the plain separator inset is used
instead of the old separator layout, such that no blank line occurs in
the LaTeX output.
Old documents are converted such that the LaTeX output remains unchanged.
As a result of this conversion, the old separator layout is replaced by
the new parbreak inset, which may also appear in places where the old
algorithm was introducing blank lines while the new one is not.
Note that not all blank lines were actually affecting the LaTeX output,
because a blank line is simply ignored by the TeX engine when it occurs
in the so called "vertical mode" (e.g., after an alignment environment).
The old ---Separator--- layout is now gone and old layout files using it
are also automatically converted.
Round trip conversions between old and new format should leave a document
unchanged. This means that the new behavior about paragraph breaking is
not "carried back" to the old format. Indeed, this would need introducing
special LaTeX commands in ERT that would accumulate in roundtrip
conversions, horribly cluttering the document. So, when converting a
modified document to old formats, the LaTeX output may slightly differ in
vertical spacing if the document is processed by an old version of LyX.
In other words, forward compatibility is guaranteed, but not backwards.
2014-05-10 21:25:11 +00:00
|
|
|
pit_type pit = cur.pit();
|
|
|
|
Paragraph const & par = pars_[pit];
|
2016-01-09 23:04:41 +00:00
|
|
|
bool lastpar = (pit == pit_type(pars_.size() - 1));
|
|
|
|
Paragraph const & nextpar = lastpar ? par : pars_[pit + 1];
|
2016-10-13 18:33:57 +00:00
|
|
|
pit_type prev = pit > 0 ? depthHook(pit, par.getDepth()) : pit;
|
2014-05-22 19:47:10 +00:00
|
|
|
if (prev < pit && cur.pos() == par.beginOfBody()
|
2016-01-13 21:49:33 +00:00
|
|
|
&& !par.size() && !par.isEnvSeparator(cur.pos())
|
2014-05-22 09:51:21 +00:00
|
|
|
&& !par.layout().isCommand()
|
2014-05-22 19:47:10 +00:00
|
|
|
&& pars_[prev].layout() != par.layout()
|
2016-01-09 23:04:41 +00:00
|
|
|
&& pars_[prev].layout().isEnvironment()
|
2016-01-13 21:49:33 +00:00
|
|
|
&& !nextpar.isEnvSeparator(nextpar.beginOfBody())) {
|
2014-05-26 19:29:33 +00:00
|
|
|
if (par.layout().isEnvironment()
|
|
|
|
&& pars_[prev].getDepth() == par.getDepth()) {
|
Fix bugs #8546 and #9055, and introduce new separator inset.
The algorithm used for breaking a paragraph in LaTeX export is changed
for avoiding spurious blank lines causing too much vertical space.
This change is tied to the introduction of a new inset (with two
different specializations) helping in either outputing LaTeX paragraph
breaks or separating environments in LyX. Both of the above goals were
previously achieved by the ---Separator--- layout and can now be
accomplished by the new inset in a more natural way. As an example,
after leaving an environment by hitting the Return key for two times,
a third return automatically inserts a parbreak inset, which is
equivalent to the old separator layout, i.e., it also introduces a
blank line in the output. If this blank line is not wanted, the
parbreak separator can be changed to a plain separator by a right
click of the mouse. Of course, an environment can still be separated
by the following one by using the Alt+P+Return shortcut (or the
corresponding menu key), but now the plain separator inset is used
instead of the old separator layout, such that no blank line occurs in
the LaTeX output.
Old documents are converted such that the LaTeX output remains unchanged.
As a result of this conversion, the old separator layout is replaced by
the new parbreak inset, which may also appear in places where the old
algorithm was introducing blank lines while the new one is not.
Note that not all blank lines were actually affecting the LaTeX output,
because a blank line is simply ignored by the TeX engine when it occurs
in the so called "vertical mode" (e.g., after an alignment environment).
The old ---Separator--- layout is now gone and old layout files using it
are also automatically converted.
Round trip conversions between old and new format should leave a document
unchanged. This means that the new behavior about paragraph breaking is
not "carried back" to the old format. Indeed, this would need introducing
special LaTeX commands in ERT that would accumulate in roundtrip
conversions, horribly cluttering the document. So, when converting a
modified document to old formats, the LaTeX output may slightly differ in
vertical spacing if the document is processed by an old version of LyX.
In other words, forward compatibility is guaranteed, but not backwards.
2014-05-10 21:25:11 +00:00
|
|
|
docstring const layout = par.layout().name();
|
|
|
|
DocumentClass const & tc = bv->buffer().params().documentClass();
|
|
|
|
lyx::dispatch(FuncRequest(LFUN_LAYOUT, tc.plainLayout().name()));
|
2016-01-14 19:57:52 +00:00
|
|
|
lyx::dispatch(FuncRequest(LFUN_SEPARATOR_INSERT, "plain"));
|
2014-05-22 09:41:23 +00:00
|
|
|
lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK, "inverse"));
|
Fix bugs #8546 and #9055, and introduce new separator inset.
The algorithm used for breaking a paragraph in LaTeX export is changed
for avoiding spurious blank lines causing too much vertical space.
This change is tied to the introduction of a new inset (with two
different specializations) helping in either outputing LaTeX paragraph
breaks or separating environments in LyX. Both of the above goals were
previously achieved by the ---Separator--- layout and can now be
accomplished by the new inset in a more natural way. As an example,
after leaving an environment by hitting the Return key for two times,
a third return automatically inserts a parbreak inset, which is
equivalent to the old separator layout, i.e., it also introduces a
blank line in the output. If this blank line is not wanted, the
parbreak separator can be changed to a plain separator by a right
click of the mouse. Of course, an environment can still be separated
by the following one by using the Alt+P+Return shortcut (or the
corresponding menu key), but now the plain separator inset is used
instead of the old separator layout, such that no blank line occurs in
the LaTeX output.
Old documents are converted such that the LaTeX output remains unchanged.
As a result of this conversion, the old separator layout is replaced by
the new parbreak inset, which may also appear in places where the old
algorithm was introducing blank lines while the new one is not.
Note that not all blank lines were actually affecting the LaTeX output,
because a blank line is simply ignored by the TeX engine when it occurs
in the so called "vertical mode" (e.g., after an alignment environment).
The old ---Separator--- layout is now gone and old layout files using it
are also automatically converted.
Round trip conversions between old and new format should leave a document
unchanged. This means that the new behavior about paragraph breaking is
not "carried back" to the old format. Indeed, this would need introducing
special LaTeX commands in ERT that would accumulate in roundtrip
conversions, horribly cluttering the document. So, when converting a
modified document to old formats, the LaTeX output may slightly differ in
vertical spacing if the document is processed by an old version of LyX.
In other words, forward compatibility is guaranteed, but not backwards.
2014-05-10 21:25:11 +00:00
|
|
|
lyx::dispatch(FuncRequest(LFUN_LAYOUT, layout));
|
|
|
|
} else {
|
2016-01-14 19:57:52 +00:00
|
|
|
lyx::dispatch(FuncRequest(LFUN_SEPARATOR_INSERT, "plain"));
|
Fix bugs #8546 and #9055, and introduce new separator inset.
The algorithm used for breaking a paragraph in LaTeX export is changed
for avoiding spurious blank lines causing too much vertical space.
This change is tied to the introduction of a new inset (with two
different specializations) helping in either outputing LaTeX paragraph
breaks or separating environments in LyX. Both of the above goals were
previously achieved by the ---Separator--- layout and can now be
accomplished by the new inset in a more natural way. As an example,
after leaving an environment by hitting the Return key for two times,
a third return automatically inserts a parbreak inset, which is
equivalent to the old separator layout, i.e., it also introduces a
blank line in the output. If this blank line is not wanted, the
parbreak separator can be changed to a plain separator by a right
click of the mouse. Of course, an environment can still be separated
by the following one by using the Alt+P+Return shortcut (or the
corresponding menu key), but now the plain separator inset is used
instead of the old separator layout, such that no blank line occurs in
the LaTeX output.
Old documents are converted such that the LaTeX output remains unchanged.
As a result of this conversion, the old separator layout is replaced by
the new parbreak inset, which may also appear in places where the old
algorithm was introducing blank lines while the new one is not.
Note that not all blank lines were actually affecting the LaTeX output,
because a blank line is simply ignored by the TeX engine when it occurs
in the so called "vertical mode" (e.g., after an alignment environment).
The old ---Separator--- layout is now gone and old layout files using it
are also automatically converted.
Round trip conversions between old and new format should leave a document
unchanged. This means that the new behavior about paragraph breaking is
not "carried back" to the old format. Indeed, this would need introducing
special LaTeX commands in ERT that would accumulate in roundtrip
conversions, horribly cluttering the document. So, when converting a
modified document to old formats, the LaTeX output may slightly differ in
vertical spacing if the document is processed by an old version of LyX.
In other words, forward compatibility is guaranteed, but not backwards.
2014-05-10 21:25:11 +00:00
|
|
|
breakParagraph(cur);
|
|
|
|
}
|
2014-05-18 15:34:11 +00:00
|
|
|
Font const f(inherit_font, cur.current_font.language());
|
|
|
|
pars_[cur.pit() - 1].resetFonts(f);
|
Fix bugs #8546 and #9055, and introduce new separator inset.
The algorithm used for breaking a paragraph in LaTeX export is changed
for avoiding spurious blank lines causing too much vertical space.
This change is tied to the introduction of a new inset (with two
different specializations) helping in either outputing LaTeX paragraph
breaks or separating environments in LyX. Both of the above goals were
previously achieved by the ---Separator--- layout and can now be
accomplished by the new inset in a more natural way. As an example,
after leaving an environment by hitting the Return key for two times,
a third return automatically inserts a parbreak inset, which is
equivalent to the old separator layout, i.e., it also introduces a
blank line in the output. If this blank line is not wanted, the
parbreak separator can be changed to a plain separator by a right
click of the mouse. Of course, an environment can still be separated
by the following one by using the Alt+P+Return shortcut (or the
corresponding menu key), but now the plain separator inset is used
instead of the old separator layout, such that no blank line occurs in
the LaTeX output.
Old documents are converted such that the LaTeX output remains unchanged.
As a result of this conversion, the old separator layout is replaced by
the new parbreak inset, which may also appear in places where the old
algorithm was introducing blank lines while the new one is not.
Note that not all blank lines were actually affecting the LaTeX output,
because a blank line is simply ignored by the TeX engine when it occurs
in the so called "vertical mode" (e.g., after an alignment environment).
The old ---Separator--- layout is now gone and old layout files using it
are also automatically converted.
Round trip conversions between old and new format should leave a document
unchanged. This means that the new behavior about paragraph breaking is
not "carried back" to the old format. Indeed, this would need introducing
special LaTeX commands in ERT that would accumulate in roundtrip
conversions, horribly cluttering the document. So, when converting a
modified document to old formats, the LaTeX output may slightly differ in
vertical spacing if the document is processed by an old version of LyX.
In other words, forward compatibility is guaranteed, but not backwards.
2014-05-10 21:25:11 +00:00
|
|
|
} else {
|
2018-01-01 11:31:31 +00:00
|
|
|
if (par.isEnvSeparator(cur.pos()) && cmd.getArg(1) != "ignoresep")
|
2016-01-09 23:04:41 +00:00
|
|
|
cur.posForward();
|
2018-01-01 11:31:31 +00:00
|
|
|
breakParagraph(cur, cmd.getArg(0) == "inverse");
|
Fix bugs #8546 and #9055, and introduce new separator inset.
The algorithm used for breaking a paragraph in LaTeX export is changed
for avoiding spurious blank lines causing too much vertical space.
This change is tied to the introduction of a new inset (with two
different specializations) helping in either outputing LaTeX paragraph
breaks or separating environments in LyX. Both of the above goals were
previously achieved by the ---Separator--- layout and can now be
accomplished by the new inset in a more natural way. As an example,
after leaving an environment by hitting the Return key for two times,
a third return automatically inserts a parbreak inset, which is
equivalent to the old separator layout, i.e., it also introduces a
blank line in the output. If this blank line is not wanted, the
parbreak separator can be changed to a plain separator by a right
click of the mouse. Of course, an environment can still be separated
by the following one by using the Alt+P+Return shortcut (or the
corresponding menu key), but now the plain separator inset is used
instead of the old separator layout, such that no blank line occurs in
the LaTeX output.
Old documents are converted such that the LaTeX output remains unchanged.
As a result of this conversion, the old separator layout is replaced by
the new parbreak inset, which may also appear in places where the old
algorithm was introducing blank lines while the new one is not.
Note that not all blank lines were actually affecting the LaTeX output,
because a blank line is simply ignored by the TeX engine when it occurs
in the so called "vertical mode" (e.g., after an alignment environment).
The old ---Separator--- layout is now gone and old layout files using it
are also automatically converted.
Round trip conversions between old and new format should leave a document
unchanged. This means that the new behavior about paragraph breaking is
not "carried back" to the old format. Indeed, this would need introducing
special LaTeX commands in ERT that would accumulate in roundtrip
conversions, horribly cluttering the document. So, when converting a
modified document to old formats, the LaTeX output may slightly differ in
vertical spacing if the document is processed by an old version of LyX.
In other words, forward compatibility is guaranteed, but not backwards.
2014-05-10 21:25:11 +00:00
|
|
|
}
|
2004-01-20 14:25:24 +00:00
|
|
|
cur.resetAnchor();
|
2015-05-28 07:46:40 +00:00
|
|
|
// If we have a list and autoinsert item insets,
|
|
|
|
// insert them now.
|
|
|
|
Layout::LaTeXArgMap args = par.layout().args();
|
|
|
|
Layout::LaTeXArgMap::const_iterator lait = args.begin();
|
|
|
|
Layout::LaTeXArgMap::const_iterator const laend = args.end();
|
|
|
|
for (; lait != laend; ++lait) {
|
|
|
|
Layout::latexarg arg = (*lait).second;
|
|
|
|
if (arg.autoinsert && prefixIs((*lait).first, "item:")) {
|
|
|
|
FuncRequest cmd(LFUN_ARGUMENT_INSERT, (*lait).first);
|
|
|
|
lyx::dispatch(cmd);
|
|
|
|
}
|
|
|
|
}
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
Fix bugs #8546 and #9055, and introduce new separator inset.
The algorithm used for breaking a paragraph in LaTeX export is changed
for avoiding spurious blank lines causing too much vertical space.
This change is tied to the introduction of a new inset (with two
different specializations) helping in either outputing LaTeX paragraph
breaks or separating environments in LyX. Both of the above goals were
previously achieved by the ---Separator--- layout and can now be
accomplished by the new inset in a more natural way. As an example,
after leaving an environment by hitting the Return key for two times,
a third return automatically inserts a parbreak inset, which is
equivalent to the old separator layout, i.e., it also introduces a
blank line in the output. If this blank line is not wanted, the
parbreak separator can be changed to a plain separator by a right
click of the mouse. Of course, an environment can still be separated
by the following one by using the Alt+P+Return shortcut (or the
corresponding menu key), but now the plain separator inset is used
instead of the old separator layout, such that no blank line occurs in
the LaTeX output.
Old documents are converted such that the LaTeX output remains unchanged.
As a result of this conversion, the old separator layout is replaced by
the new parbreak inset, which may also appear in places where the old
algorithm was introducing blank lines while the new one is not.
Note that not all blank lines were actually affecting the LaTeX output,
because a blank line is simply ignored by the TeX engine when it occurs
in the so called "vertical mode" (e.g., after an alignment environment).
The old ---Separator--- layout is now gone and old layout files using it
are also automatically converted.
Round trip conversions between old and new format should leave a document
unchanged. This means that the new behavior about paragraph breaking is
not "carried back" to the old format. Indeed, this would need introducing
special LaTeX commands in ERT that would accumulate in roundtrip
conversions, horribly cluttering the document. So, when converting a
modified document to old formats, the LaTeX output may slightly differ in
vertical spacing if the document is processed by an old version of LyX.
In other words, forward compatibility is guaranteed, but not backwards.
2014-05-10 21:25:11 +00:00
|
|
|
}
|
2002-08-20 15:26:52 +00:00
|
|
|
|
2003-11-13 20:16:34 +00:00
|
|
|
case LFUN_INSET_INSERT: {
|
2007-10-18 11:51:17 +00:00
|
|
|
cur.recordUndo();
|
2008-12-21 01:53:47 +00:00
|
|
|
|
|
|
|
// We have to avoid triggering InstantPreview loading
|
|
|
|
// before inserting into the document. See bug #5626.
|
|
|
|
bool loaded = bv->buffer().isFullyLoaded();
|
|
|
|
bv->buffer().setFullyLoaded(false);
|
2009-11-08 15:53:21 +00:00
|
|
|
Inset * inset = createInset(&bv->buffer(), cmd);
|
2008-12-21 01:53:47 +00:00
|
|
|
bv->buffer().setFullyLoaded(loaded);
|
|
|
|
|
2004-08-12 19:49:25 +00:00
|
|
|
if (inset) {
|
2007-02-02 10:31:22 +00:00
|
|
|
// FIXME (Abdel 01/02/2006):
|
|
|
|
// What follows would be a partial fix for bug 2154:
|
2009-12-11 00:59:10 +00:00
|
|
|
// http://www.lyx.org/trac/ticket/2154
|
2007-05-28 22:27:45 +00:00
|
|
|
// This automatically put the label inset _after_ a
|
2007-02-02 10:31:22 +00:00
|
|
|
// numbered section. It should be possible to extend the mechanism
|
2007-02-01 17:21:05 +00:00
|
|
|
// to any kind of LateX environement.
|
2007-02-02 10:31:22 +00:00
|
|
|
// The correct way to fix that bug would be at LateX generation.
|
|
|
|
// I'll let the code here for reference as it could be used for some
|
|
|
|
// other feature like "automatic labelling".
|
|
|
|
/*
|
|
|
|
Paragraph & par = pars_[cur.pit()];
|
2007-10-13 09:04:52 +00:00
|
|
|
if (inset->lyxCode() == LABEL_CODE
|
2015-02-15 00:04:41 +00:00
|
|
|
&& !par.layout().counter.empty()) {
|
2007-02-01 17:21:05 +00:00
|
|
|
// Go to the end of the paragraph
|
|
|
|
// Warning: Because of Change-Tracking, the last
|
|
|
|
// position is 'size()' and not 'size()-1':
|
|
|
|
cur.pos() = par.size();
|
|
|
|
// Insert a new paragraph
|
2015-02-15 00:04:41 +00:00
|
|
|
FuncRequest fr(LFUN_PARAGRAPH_BREAK);
|
2007-02-01 17:36:56 +00:00
|
|
|
dispatch(cur, fr);
|
2007-02-01 17:21:05 +00:00
|
|
|
}
|
2007-02-02 10:31:22 +00:00
|
|
|
*/
|
2007-07-30 10:33:43 +00:00
|
|
|
if (cur.selection())
|
|
|
|
cutSelection(cur, true, false);
|
2008-03-02 18:49:49 +00:00
|
|
|
cur.insert(inset);
|
2018-01-05 18:29:45 +00:00
|
|
|
cur.forceBufferUpdate();
|
2010-11-21 17:00:12 +00:00
|
|
|
if (inset->editable() && inset->asInsetText())
|
|
|
|
inset->edit(cur, true);
|
|
|
|
else
|
|
|
|
cur.posForward();
|
2008-12-21 01:53:47 +00:00
|
|
|
|
|
|
|
// trigger InstantPreview now
|
|
|
|
if (inset->lyxCode() == EXTERNAL_CODE) {
|
2008-12-22 10:51:09 +00:00
|
|
|
InsetExternal & ins =
|
|
|
|
static_cast<InsetExternal &>(*inset);
|
2008-12-21 01:53:47 +00:00
|
|
|
ins.updatePreview();
|
|
|
|
}
|
2004-08-12 19:49:25 +00:00
|
|
|
}
|
2008-12-21 01:53:47 +00:00
|
|
|
|
2003-11-13 20:16:34 +00:00
|
|
|
break;
|
2003-12-12 10:05:21 +00:00
|
|
|
}
|
2003-11-13 20:16:34 +00:00
|
|
|
|
2008-12-22 10:24:43 +00:00
|
|
|
case LFUN_INSET_DISSOLVE: {
|
2010-07-09 14:37:00 +00:00
|
|
|
if (dissolveInset(cur)) {
|
2008-12-22 10:24:43 +00:00
|
|
|
needsUpdate = true;
|
2010-07-09 14:37:00 +00:00
|
|
|
cur.forceBufferUpdate();
|
|
|
|
}
|
2006-08-08 13:34:02 +00:00
|
|
|
break;
|
2008-12-22 10:24:43 +00:00
|
|
|
}
|
2006-08-08 13:34:02 +00:00
|
|
|
|
2008-05-06 21:13:09 +00:00
|
|
|
case LFUN_SET_GRAPHICS_GROUP: {
|
2008-05-27 12:06:34 +00:00
|
|
|
InsetGraphics * ins = graphics::getCurrentGraphicsInset(cur);
|
2008-05-07 23:40:59 +00:00
|
|
|
if (!ins)
|
|
|
|
break;
|
2008-05-06 21:13:09 +00:00
|
|
|
|
2008-09-18 10:40:53 +00:00
|
|
|
cur.recordUndo();
|
2008-05-06 21:13:09 +00:00
|
|
|
|
|
|
|
string id = to_utf8(cmd.argument());
|
2008-05-27 12:06:34 +00:00
|
|
|
string grp = graphics::getGroupParams(bv->buffer(), id);
|
2008-05-07 14:44:58 +00:00
|
|
|
InsetGraphicsParams tmp, inspar = ins->getParams();
|
2008-05-06 21:13:09 +00:00
|
|
|
|
|
|
|
if (id.empty())
|
|
|
|
inspar.groupId = to_utf8(cmd.argument());
|
|
|
|
else {
|
|
|
|
InsetGraphics::string2params(grp, bv->buffer(), tmp);
|
|
|
|
tmp.filename = inspar.filename;
|
|
|
|
inspar = tmp;
|
|
|
|
}
|
|
|
|
|
2008-05-07 14:44:58 +00:00
|
|
|
ins->setParams(inspar);
|
2017-08-12 07:55:06 +00:00
|
|
|
break;
|
2008-05-06 21:13:09 +00:00
|
|
|
}
|
|
|
|
|
2003-05-22 10:40:57 +00:00
|
|
|
case LFUN_SPACE_INSERT:
|
2008-03-06 21:31:27 +00:00
|
|
|
if (cur.paragraph().layout().free_spacing)
|
2004-02-13 07:30:59 +00:00
|
|
|
insertChar(cur, ' ');
|
2004-11-02 14:25:14 +00:00
|
|
|
else {
|
2004-02-13 11:05:29 +00:00
|
|
|
doInsertInset(cur, this, cmd, false, false);
|
2007-11-05 19:41:16 +00:00
|
|
|
cur.posForward();
|
2004-11-02 14:25:14 +00:00
|
|
|
}
|
2004-01-20 14:25:24 +00:00
|
|
|
moveCursor(cur, false);
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2007-12-06 11:04:56 +00:00
|
|
|
case LFUN_SPECIALCHAR_INSERT: {
|
|
|
|
string const name = to_utf8(cmd.argument());
|
|
|
|
if (name == "hyphenation")
|
|
|
|
specialChar(cur, InsetSpecialChar::HYPHENATION);
|
2017-03-06 13:49:30 +00:00
|
|
|
else if (name == "allowbreak")
|
|
|
|
specialChar(cur, InsetSpecialChar::ALLOWBREAK);
|
2007-12-06 11:04:56 +00:00
|
|
|
else if (name == "ligature-break")
|
|
|
|
specialChar(cur, InsetSpecialChar::LIGATURE_BREAK);
|
|
|
|
else if (name == "slash")
|
|
|
|
specialChar(cur, InsetSpecialChar::SLASH);
|
|
|
|
else if (name == "nobreakdash")
|
|
|
|
specialChar(cur, InsetSpecialChar::NOBREAKDASH);
|
|
|
|
else if (name == "dots")
|
|
|
|
specialChar(cur, InsetSpecialChar::LDOTS);
|
|
|
|
else if (name == "end-of-sentence")
|
|
|
|
specialChar(cur, InsetSpecialChar::END_OF_SENTENCE);
|
|
|
|
else if (name == "menu-separator")
|
|
|
|
specialChar(cur, InsetSpecialChar::MENU_SEPARATOR);
|
2015-03-01 10:16:57 +00:00
|
|
|
else if (name == "lyx")
|
|
|
|
specialChar(cur, InsetSpecialChar::PHRASE_LYX);
|
|
|
|
else if (name == "tex")
|
|
|
|
specialChar(cur, InsetSpecialChar::PHRASE_TEX);
|
|
|
|
else if (name == "latex")
|
|
|
|
specialChar(cur, InsetSpecialChar::PHRASE_LATEX);
|
|
|
|
else if (name == "latex2e")
|
|
|
|
specialChar(cur, InsetSpecialChar::PHRASE_LATEX2E);
|
2007-12-06 11:04:56 +00:00
|
|
|
else if (name.empty())
|
|
|
|
lyxerr << "LyX function 'specialchar-insert' needs an argument." << endl;
|
|
|
|
else
|
|
|
|
lyxerr << "Wrong argument for LyX function 'specialchar-insert'." << endl;
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
2007-12-06 11:04:56 +00:00
|
|
|
}
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2012-08-23 15:42:53 +00:00
|
|
|
case LFUN_IPAMACRO_INSERT: {
|
|
|
|
string const arg = cmd.getArg(0);
|
|
|
|
if (arg == "deco") {
|
|
|
|
// Open the inset, and move the current selection
|
|
|
|
// inside it.
|
|
|
|
doInsertInset(cur, this, cmd, true, true);
|
|
|
|
cur.posForward();
|
|
|
|
// Some insets are numbered, others are shown in the outline pane so
|
|
|
|
// let's update the labels and the toc backend.
|
|
|
|
cur.forceBufferUpdate();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (arg == "tone-falling")
|
|
|
|
ipaChar(cur, InsetIPAChar::TONE_FALLING);
|
|
|
|
else if (arg == "tone-rising")
|
|
|
|
ipaChar(cur, InsetIPAChar::TONE_RISING);
|
|
|
|
else if (arg == "tone-high-rising")
|
|
|
|
ipaChar(cur, InsetIPAChar::TONE_HIGH_RISING);
|
|
|
|
else if (arg == "tone-low-rising")
|
|
|
|
ipaChar(cur, InsetIPAChar::TONE_LOW_RISING);
|
|
|
|
else if (arg == "tone-high-rising-falling")
|
|
|
|
ipaChar(cur, InsetIPAChar::TONE_HIGH_RISING_FALLING);
|
|
|
|
else if (arg.empty())
|
|
|
|
lyxerr << "LyX function 'ipamacro-insert' needs an argument." << endl;
|
|
|
|
else
|
|
|
|
lyxerr << "Wrong argument for LyX function 'ipamacro-insert'." << endl;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_WORD_UPCASE:
|
2015-05-28 13:43:12 +00:00
|
|
|
changeCase(cur, text_uppercase, cmd.getArg(0) == "partial");
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_WORD_LOWCASE:
|
2015-05-28 13:43:12 +00:00
|
|
|
changeCase(cur, text_lowercase, cmd.getArg(0) == "partial");
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_WORD_CAPITALIZE:
|
2015-05-28 13:43:12 +00:00
|
|
|
changeCase(cur, text_capitalization, cmd.getArg(0) == "partial");
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_CHARS_TRANSPOSE:
|
2007-05-28 22:27:45 +00:00
|
|
|
charsTranspose(cur);
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2008-02-03 10:43:03 +00:00
|
|
|
case LFUN_PASTE: {
|
2006-09-11 08:54:10 +00:00
|
|
|
cur.message(_("Paste"));
|
2013-04-25 21:27:10 +00:00
|
|
|
LASSERT(cur.selBegin().idx() == cur.selEnd().idx(), break);
|
2006-10-21 00:16:43 +00:00
|
|
|
cap::replaceSelection(cur);
|
2008-02-03 10:43:03 +00:00
|
|
|
|
|
|
|
// without argument?
|
|
|
|
string const arg = to_utf8(cmd.argument());
|
|
|
|
if (arg.empty()) {
|
2013-07-13 08:29:54 +00:00
|
|
|
bool tryGraphics = true;
|
2008-02-03 10:43:03 +00:00
|
|
|
if (theClipboard().isInternal())
|
|
|
|
pasteFromStack(cur, bv->buffer().errorList("Paste"), 0);
|
2013-07-13 08:29:54 +00:00
|
|
|
else if (theClipboard().hasTextContents()) {
|
|
|
|
if (pasteClipboardText(cur, bv->buffer().errorList("Paste"),
|
|
|
|
true, Clipboard::AnyTextType))
|
|
|
|
tryGraphics = false;
|
|
|
|
}
|
|
|
|
if (tryGraphics && theClipboard().hasGraphicsContents())
|
2008-02-03 10:43:03 +00:00
|
|
|
pasteClipboardGraphics(cur, bv->buffer().errorList("Paste"));
|
|
|
|
} else if (isStrUnsignedInt(arg)) {
|
|
|
|
// we have a numerical argument
|
2007-08-21 13:03:55 +00:00
|
|
|
pasteFromStack(cur, bv->buffer().errorList("Paste"),
|
2008-02-03 10:43:03 +00:00
|
|
|
convert<unsigned int>(arg));
|
2013-04-14 17:45:36 +00:00
|
|
|
} else if (arg == "html" || arg == "latex") {
|
|
|
|
Clipboard::TextType type = (arg == "html") ?
|
|
|
|
Clipboard::HtmlTextType : Clipboard::LaTeXTextType;
|
|
|
|
pasteClipboardText(cur, bv->buffer().errorList("Paste"), true, type);
|
2008-02-03 10:43:03 +00:00
|
|
|
} else {
|
2008-03-04 14:04:59 +00:00
|
|
|
Clipboard::GraphicsType type = Clipboard::AnyGraphicsType;
|
2008-02-03 10:43:03 +00:00
|
|
|
if (arg == "pdf")
|
|
|
|
type = Clipboard::PdfGraphicsType;
|
|
|
|
else if (arg == "png")
|
|
|
|
type = Clipboard::PngGraphicsType;
|
|
|
|
else if (arg == "jpeg")
|
|
|
|
type = Clipboard::JpegGraphicsType;
|
|
|
|
else if (arg == "linkback")
|
|
|
|
type = Clipboard::LinkBackGraphicsType;
|
2009-05-03 11:22:01 +00:00
|
|
|
else if (arg == "emf")
|
|
|
|
type = Clipboard::EmfGraphicsType;
|
|
|
|
else if (arg == "wmf")
|
|
|
|
type = Clipboard::WmfGraphicsType;
|
2008-02-03 10:43:03 +00:00
|
|
|
else
|
2015-04-22 03:22:21 +00:00
|
|
|
// we also check in getStatus()
|
2013-04-25 21:27:10 +00:00
|
|
|
LYXERR0("Unrecognized graphics type: " << arg);
|
2008-02-03 10:43:03 +00:00
|
|
|
|
|
|
|
pasteClipboardGraphics(cur, bv->buffer().errorList("Paste"), type);
|
2007-01-04 12:05:24 +00:00
|
|
|
}
|
2008-02-03 10:43:03 +00:00
|
|
|
|
2007-08-21 13:03:55 +00:00
|
|
|
bv->buffer().errors("Paste");
|
2004-01-20 14:25:24 +00:00
|
|
|
cur.clearSelection(); // bug 393
|
2007-10-18 11:51:17 +00:00
|
|
|
cur.finishUndo();
|
2002-08-26 13:25:49 +00:00
|
|
|
break;
|
2008-02-03 10:43:03 +00:00
|
|
|
}
|
2002-08-26 13:25:49 +00:00
|
|
|
|
|
|
|
case LFUN_CUT:
|
2004-02-13 11:05:29 +00:00
|
|
|
cutSelection(cur, true, true);
|
2006-09-11 08:54:10 +00:00
|
|
|
cur.message(_("Cut"));
|
2002-08-26 13:25:49 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case LFUN_COPY:
|
2004-02-13 11:05:29 +00:00
|
|
|
copySelection(cur);
|
2006-09-11 08:54:10 +00:00
|
|
|
cur.message(_("Copy"));
|
2002-08-26 13:25:49 +00:00
|
|
|
break;
|
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_SERVER_GET_XY:
|
2006-10-21 00:16:43 +00:00
|
|
|
cur.message(from_utf8(
|
2009-05-14 12:35:04 +00:00
|
|
|
convert<string>(tm->cursorX(cur.top(), cur.boundary()))
|
|
|
|
+ ' ' + convert<string>(tm->cursorY(cur.top(), cur.boundary()))));
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_SERVER_SET_XY: {
|
2002-08-20 13:00:25 +00:00
|
|
|
int x = 0;
|
|
|
|
int y = 0;
|
2006-10-21 00:16:43 +00:00
|
|
|
istringstream is(to_utf8(cmd.argument()));
|
2002-08-21 06:50:42 +00:00
|
|
|
is >> x >> y;
|
|
|
|
if (!is)
|
2002-08-20 13:00:25 +00:00
|
|
|
lyxerr << "SETXY: Could not parse coordinates in '"
|
2007-12-12 19:28:07 +00:00
|
|
|
<< to_utf8(cmd.argument()) << endl;
|
2002-11-27 10:30:28 +00:00
|
|
|
else
|
2009-05-14 12:35:04 +00:00
|
|
|
tm->setCursorFromCoordinates(cur, x, y);
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
2002-08-20 13:00:25 +00:00
|
|
|
}
|
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_SERVER_GET_LAYOUT:
|
2008-03-06 21:31:27 +00:00
|
|
|
cur.message(cur.paragraph().layout().name());
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case LFUN_LAYOUT: {
|
2018-01-01 11:27:08 +00:00
|
|
|
bool const ignoreautonests = cmd.getArg(1) == "ignoreautonests";
|
|
|
|
docstring layout = ignoreautonests ? from_utf8(cmd.getArg(0)) : cmd.argument();
|
2007-11-15 20:04:51 +00:00
|
|
|
LYXERR(Debug::INFO, "LFUN_LAYOUT: (arg) " << to_utf8(layout));
|
2002-08-20 15:26:52 +00:00
|
|
|
|
Fix bug 4037 and related problems. The patch has been cleaned up a bit
from the one posted to the list.
The basic idea has two parts. First, we hard code an "empty layout"
(called PlainLayout, for want of a better name) in TextClass and read it
before doing anything else. It can therefore be customized by classes,
if they want---say, to make it left-aligned. Second, InsetText's are
divided into three types: (i) normal ones, that use the "default" layout
defined by the text class; (ii) highly restrictive ones, such as ERT and
(not quite an inset) table cells, which demand the empty layout; (iii)
middling ones, which default to an empty layout and use the empty layout
in place of the default. (This is so we don't get the same problem we
had with ERT in e.g. footnotes.) The type of inset is signaled by new
methods InsetText::forceEmptyLayout() and InsetText::useEmptyLayout().
(The latter might better be called: useEmptyLayoutInsteadOfDefault(),
but that's silly.) The old InsetText::forceDefaultParagraphs() has been
split into these, plus a new method InsetText::allowParagraphCustomization().
A lot of the changes just adapt to this change.
The other big change is in GuiToolbar: We want to show LyXDefault and
the "default" layout only when they're active.
There are a handful of places where I'm not entirely sure whether we
should be using forceEmptyLayout or !allowParagraphCustomization() or
both. The InsetCaption is one of these. These places, and some others,
are marked with FIXMEs, so I'd appreciate it if people would search
through the patch and let me know whether these need changing. If they
don't, the FIXMEs can be deleted.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@22966 a592a061-630c-0410-9148-cb99ea01b6c8
2008-02-12 17:31:07 +00:00
|
|
|
Paragraph const & para = cur.paragraph();
|
2008-03-06 21:31:27 +00:00
|
|
|
docstring const old_layout = para.layout().name();
|
2008-02-28 01:42:02 +00:00
|
|
|
DocumentClass const & tclass = bv->buffer().params().documentClass();
|
Fix bug 4037 and related problems. The patch has been cleaned up a bit
from the one posted to the list.
The basic idea has two parts. First, we hard code an "empty layout"
(called PlainLayout, for want of a better name) in TextClass and read it
before doing anything else. It can therefore be customized by classes,
if they want---say, to make it left-aligned. Second, InsetText's are
divided into three types: (i) normal ones, that use the "default" layout
defined by the text class; (ii) highly restrictive ones, such as ERT and
(not quite an inset) table cells, which demand the empty layout; (iii)
middling ones, which default to an empty layout and use the empty layout
in place of the default. (This is so we don't get the same problem we
had with ERT in e.g. footnotes.) The type of inset is signaled by new
methods InsetText::forceEmptyLayout() and InsetText::useEmptyLayout().
(The latter might better be called: useEmptyLayoutInsteadOfDefault(),
but that's silly.) The old InsetText::forceDefaultParagraphs() has been
split into these, plus a new method InsetText::allowParagraphCustomization().
A lot of the changes just adapt to this change.
The other big change is in GuiToolbar: We want to show LyXDefault and
the "default" layout only when they're active.
There are a handful of places where I'm not entirely sure whether we
should be using forceEmptyLayout or !allowParagraphCustomization() or
both. The InsetCaption is one of these. These places, and some others,
are marked with FIXMEs, so I'd appreciate it if people would search
through the patch and let me know whether these need changing. If they
don't, the FIXMEs can be deleted.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@22966 a592a061-630c-0410-9148-cb99ea01b6c8
2008-02-12 17:31:07 +00:00
|
|
|
|
2006-11-16 08:17:48 +00:00
|
|
|
if (layout.empty())
|
|
|
|
layout = tclass.defaultLayoutName();
|
Fix bug 4037 and related problems. The patch has been cleaned up a bit
from the one posted to the list.
The basic idea has two parts. First, we hard code an "empty layout"
(called PlainLayout, for want of a better name) in TextClass and read it
before doing anything else. It can therefore be customized by classes,
if they want---say, to make it left-aligned. Second, InsetText's are
divided into three types: (i) normal ones, that use the "default" layout
defined by the text class; (ii) highly restrictive ones, such as ERT and
(not quite an inset) table cells, which demand the empty layout; (iii)
middling ones, which default to an empty layout and use the empty layout
in place of the default. (This is so we don't get the same problem we
had with ERT in e.g. footnotes.) The type of inset is signaled by new
methods InsetText::forceEmptyLayout() and InsetText::useEmptyLayout().
(The latter might better be called: useEmptyLayoutInsteadOfDefault(),
but that's silly.) The old InsetText::forceDefaultParagraphs() has been
split into these, plus a new method InsetText::allowParagraphCustomization().
A lot of the changes just adapt to this change.
The other big change is in GuiToolbar: We want to show LyXDefault and
the "default" layout only when they're active.
There are a handful of places where I'm not entirely sure whether we
should be using forceEmptyLayout or !allowParagraphCustomization() or
both. The InsetCaption is one of these. These places, and some others,
are marked with FIXMEs, so I'd appreciate it if people would search
through the patch and let me know whether these need changing. If they
don't, the FIXMEs can be deleted.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@22966 a592a061-630c-0410-9148-cb99ea01b6c8
2008-02-12 17:31:07 +00:00
|
|
|
|
2009-08-09 15:29:34 +00:00
|
|
|
if (owner_->forcePlainLayout())
|
Fix bug 4037 and related problems. The patch has been cleaned up a bit
from the one posted to the list.
The basic idea has two parts. First, we hard code an "empty layout"
(called PlainLayout, for want of a better name) in TextClass and read it
before doing anything else. It can therefore be customized by classes,
if they want---say, to make it left-aligned. Second, InsetText's are
divided into three types: (i) normal ones, that use the "default" layout
defined by the text class; (ii) highly restrictive ones, such as ERT and
(not quite an inset) table cells, which demand the empty layout; (iii)
middling ones, which default to an empty layout and use the empty layout
in place of the default. (This is so we don't get the same problem we
had with ERT in e.g. footnotes.) The type of inset is signaled by new
methods InsetText::forceEmptyLayout() and InsetText::useEmptyLayout().
(The latter might better be called: useEmptyLayoutInsteadOfDefault(),
but that's silly.) The old InsetText::forceDefaultParagraphs() has been
split into these, plus a new method InsetText::allowParagraphCustomization().
A lot of the changes just adapt to this change.
The other big change is in GuiToolbar: We want to show LyXDefault and
the "default" layout only when they're active.
There are a handful of places where I'm not entirely sure whether we
should be using forceEmptyLayout or !allowParagraphCustomization() or
both. The InsetCaption is one of these. These places, and some others,
are marked with FIXMEs, so I'd appreciate it if people would search
through the patch and let me know whether these need changing. If they
don't, the FIXMEs can be deleted.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@22966 a592a061-630c-0410-9148-cb99ea01b6c8
2008-02-12 17:31:07 +00:00
|
|
|
// in this case only the empty layout is allowed
|
2008-08-01 20:57:27 +00:00
|
|
|
layout = tclass.plainLayoutName();
|
2008-07-10 17:41:52 +00:00
|
|
|
else if (para.usePlainLayout()) {
|
2008-10-13 11:25:37 +00:00
|
|
|
// in this case, default layout maps to empty layout
|
Fix bug 4037 and related problems. The patch has been cleaned up a bit
from the one posted to the list.
The basic idea has two parts. First, we hard code an "empty layout"
(called PlainLayout, for want of a better name) in TextClass and read it
before doing anything else. It can therefore be customized by classes,
if they want---say, to make it left-aligned. Second, InsetText's are
divided into three types: (i) normal ones, that use the "default" layout
defined by the text class; (ii) highly restrictive ones, such as ERT and
(not quite an inset) table cells, which demand the empty layout; (iii)
middling ones, which default to an empty layout and use the empty layout
in place of the default. (This is so we don't get the same problem we
had with ERT in e.g. footnotes.) The type of inset is signaled by new
methods InsetText::forceEmptyLayout() and InsetText::useEmptyLayout().
(The latter might better be called: useEmptyLayoutInsteadOfDefault(),
but that's silly.) The old InsetText::forceDefaultParagraphs() has been
split into these, plus a new method InsetText::allowParagraphCustomization().
A lot of the changes just adapt to this change.
The other big change is in GuiToolbar: We want to show LyXDefault and
the "default" layout only when they're active.
There are a handful of places where I'm not entirely sure whether we
should be using forceEmptyLayout or !allowParagraphCustomization() or
both. The InsetCaption is one of these. These places, and some others,
are marked with FIXMEs, so I'd appreciate it if people would search
through the patch and let me know whether these need changing. If they
don't, the FIXMEs can be deleted.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@22966 a592a061-630c-0410-9148-cb99ea01b6c8
2008-02-12 17:31:07 +00:00
|
|
|
if (layout == tclass.defaultLayoutName())
|
2008-08-01 20:57:27 +00:00
|
|
|
layout = tclass.plainLayoutName();
|
2008-10-13 11:25:37 +00:00
|
|
|
} else {
|
Fix bug 4037 and related problems. The patch has been cleaned up a bit
from the one posted to the list.
The basic idea has two parts. First, we hard code an "empty layout"
(called PlainLayout, for want of a better name) in TextClass and read it
before doing anything else. It can therefore be customized by classes,
if they want---say, to make it left-aligned. Second, InsetText's are
divided into three types: (i) normal ones, that use the "default" layout
defined by the text class; (ii) highly restrictive ones, such as ERT and
(not quite an inset) table cells, which demand the empty layout; (iii)
middling ones, which default to an empty layout and use the empty layout
in place of the default. (This is so we don't get the same problem we
had with ERT in e.g. footnotes.) The type of inset is signaled by new
methods InsetText::forceEmptyLayout() and InsetText::useEmptyLayout().
(The latter might better be called: useEmptyLayoutInsteadOfDefault(),
but that's silly.) The old InsetText::forceDefaultParagraphs() has been
split into these, plus a new method InsetText::allowParagraphCustomization().
A lot of the changes just adapt to this change.
The other big change is in GuiToolbar: We want to show LyXDefault and
the "default" layout only when they're active.
There are a handful of places where I'm not entirely sure whether we
should be using forceEmptyLayout or !allowParagraphCustomization() or
both. The InsetCaption is one of these. These places, and some others,
are marked with FIXMEs, so I'd appreciate it if people would search
through the patch and let me know whether these need changing. If they
don't, the FIXMEs can be deleted.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@22966 a592a061-630c-0410-9148-cb99ea01b6c8
2008-02-12 17:31:07 +00:00
|
|
|
// otherwise, the empty layout maps to the default
|
2008-08-01 20:57:27 +00:00
|
|
|
if (layout == tclass.plainLayoutName())
|
Fix bug 4037 and related problems. The patch has been cleaned up a bit
from the one posted to the list.
The basic idea has two parts. First, we hard code an "empty layout"
(called PlainLayout, for want of a better name) in TextClass and read it
before doing anything else. It can therefore be customized by classes,
if they want---say, to make it left-aligned. Second, InsetText's are
divided into three types: (i) normal ones, that use the "default" layout
defined by the text class; (ii) highly restrictive ones, such as ERT and
(not quite an inset) table cells, which demand the empty layout; (iii)
middling ones, which default to an empty layout and use the empty layout
in place of the default. (This is so we don't get the same problem we
had with ERT in e.g. footnotes.) The type of inset is signaled by new
methods InsetText::forceEmptyLayout() and InsetText::useEmptyLayout().
(The latter might better be called: useEmptyLayoutInsteadOfDefault(),
but that's silly.) The old InsetText::forceDefaultParagraphs() has been
split into these, plus a new method InsetText::allowParagraphCustomization().
A lot of the changes just adapt to this change.
The other big change is in GuiToolbar: We want to show LyXDefault and
the "default" layout only when they're active.
There are a handful of places where I'm not entirely sure whether we
should be using forceEmptyLayout or !allowParagraphCustomization() or
both. The InsetCaption is one of these. These places, and some others,
are marked with FIXMEs, so I'd appreciate it if people would search
through the patch and let me know whether these need changing. If they
don't, the FIXMEs can be deleted.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@22966 a592a061-630c-0410-9148-cb99ea01b6c8
2008-02-12 17:31:07 +00:00
|
|
|
layout = tclass.defaultLayoutName();
|
|
|
|
}
|
|
|
|
|
2006-11-16 08:17:48 +00:00
|
|
|
bool hasLayout = tclass.hasLayout(layout);
|
2002-08-20 15:26:52 +00:00
|
|
|
|
|
|
|
// If the entry is obsolete, use the new one instead.
|
|
|
|
if (hasLayout) {
|
2008-03-06 20:01:30 +00:00
|
|
|
docstring const & obs = tclass[layout].obsoleted_by();
|
2002-08-20 15:26:52 +00:00
|
|
|
if (!obs.empty())
|
|
|
|
layout = obs;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!hasLayout) {
|
2006-10-21 00:16:43 +00:00
|
|
|
cur.errorMessage(from_utf8(N_("Layout ")) + cmd.argument() +
|
|
|
|
from_utf8(N_(" not known")));
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2007-10-01 20:45:50 +00:00
|
|
|
bool change_layout = (old_layout != layout);
|
2003-05-19 07:12:09 +00:00
|
|
|
|
2004-01-20 14:25:24 +00:00
|
|
|
if (!change_layout && cur.selection() &&
|
2004-11-24 21:53:46 +00:00
|
|
|
cur.selBegin().pit() != cur.selEnd().pit())
|
2002-08-20 15:26:52 +00:00
|
|
|
{
|
2004-11-24 21:53:46 +00:00
|
|
|
pit_type spit = cur.selBegin().pit();
|
|
|
|
pit_type epit = cur.selEnd().pit() + 1;
|
2003-04-09 09:15:20 +00:00
|
|
|
while (spit != epit) {
|
2008-03-06 21:31:27 +00:00
|
|
|
if (pars_[spit].layout().name() != old_layout) {
|
2002-08-20 15:26:52 +00:00
|
|
|
change_layout = true;
|
|
|
|
break;
|
|
|
|
}
|
2003-04-09 09:15:20 +00:00
|
|
|
++spit;
|
2002-08-20 15:26:52 +00:00
|
|
|
}
|
|
|
|
}
|
2003-05-19 07:12:09 +00:00
|
|
|
|
2018-01-01 11:27:08 +00:00
|
|
|
if (change_layout) {
|
2004-02-13 07:30:59 +00:00
|
|
|
setLayout(cur, layout);
|
2018-01-01 11:27:08 +00:00
|
|
|
if (cur.pit() > 0 && !ignoreautonests) {
|
|
|
|
set<docstring> const & autonests =
|
|
|
|
pars_[cur.pit() - 1].layout().autonests();
|
|
|
|
set<docstring> const & autonested =
|
|
|
|
pars_[cur.pit()].layout().isAutonestedBy();
|
|
|
|
if (autonests.find(layout) != autonests.end()
|
|
|
|
|| autonested.find(old_layout) != autonested.end())
|
|
|
|
lyx::dispatch(FuncRequest(LFUN_DEPTH_INCREMENT));
|
|
|
|
}
|
|
|
|
}
|
2007-10-01 20:45:50 +00:00
|
|
|
|
2012-12-16 13:10:03 +00:00
|
|
|
Layout::LaTeXArgMap args = tclass[layout].args();
|
2012-12-16 12:37:14 +00:00
|
|
|
Layout::LaTeXArgMap::const_iterator lait = args.begin();
|
|
|
|
Layout::LaTeXArgMap::const_iterator const laend = args.end();
|
|
|
|
for (; lait != laend; ++lait) {
|
|
|
|
Layout::latexarg arg = (*lait).second;
|
|
|
|
if (arg.autoinsert) {
|
|
|
|
FuncRequest cmd(LFUN_ARGUMENT_INSERT, (*lait).first);
|
|
|
|
lyx::dispatch(cmd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2012-12-23 17:57:32 +00:00
|
|
|
case LFUN_ENVIRONMENT_SPLIT: {
|
2014-01-27 07:01:24 +00:00
|
|
|
bool const outer = cmd.argument() == "outer";
|
2018-01-01 11:34:39 +00:00
|
|
|
bool const previous = cmd.argument() == "previous";
|
|
|
|
bool const before = cmd.argument() == "before";
|
|
|
|
bool const normal = cmd.argument().empty();
|
2012-12-23 17:57:32 +00:00
|
|
|
Paragraph const & para = cur.paragraph();
|
2018-01-01 11:34:39 +00:00
|
|
|
docstring layout;
|
|
|
|
if (para.layout().isEnvironment())
|
|
|
|
layout = para.layout().name();
|
2014-01-27 07:01:24 +00:00
|
|
|
depth_type split_depth = cur.paragraph().params().depth();
|
2018-01-01 11:34:39 +00:00
|
|
|
depth_type nextpar_depth = 0;
|
|
|
|
if (outer || previous) {
|
|
|
|
// check if we have an environment in our scope
|
2014-01-27 07:01:24 +00:00
|
|
|
pit_type pit = cur.pit();
|
|
|
|
Paragraph cpar = pars_[pit];
|
|
|
|
while (true) {
|
2018-01-01 11:34:39 +00:00
|
|
|
if (pit == 0)
|
2014-01-27 07:01:24 +00:00
|
|
|
break;
|
|
|
|
--pit;
|
|
|
|
cpar = pars_[pit];
|
2018-01-01 11:34:39 +00:00
|
|
|
if (layout.empty() && previous
|
|
|
|
&& cpar.layout().isEnvironment()
|
|
|
|
&& cpar.params().depth() <= split_depth)
|
|
|
|
layout = cpar.layout().name();
|
2014-01-27 07:01:24 +00:00
|
|
|
if (cpar.params().depth() < split_depth
|
|
|
|
&& cpar.layout().isEnvironment()) {
|
2018-01-01 11:34:39 +00:00
|
|
|
if (!previous)
|
|
|
|
layout = cpar.layout().name();
|
2014-01-27 07:01:24 +00:00
|
|
|
split_depth = cpar.params().depth();
|
|
|
|
}
|
2018-01-01 11:34:39 +00:00
|
|
|
if (cpar.params().depth() == 0)
|
|
|
|
break;
|
2014-01-27 07:01:24 +00:00
|
|
|
}
|
|
|
|
}
|
2018-01-01 11:34:39 +00:00
|
|
|
if ((outer || normal) && cur.pit() < cur.lastpit()) {
|
|
|
|
// save nesting of following paragraph
|
|
|
|
Paragraph cpar = pars_[cur.pit() + 1];
|
|
|
|
nextpar_depth = cpar.params().depth();
|
|
|
|
}
|
|
|
|
if (before)
|
|
|
|
cur.top().setPitPos(cur.pit(), 0);
|
|
|
|
if (before || cur.pos() > 0)
|
2012-12-24 10:22:23 +00:00
|
|
|
lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK));
|
2018-01-01 11:34:39 +00:00
|
|
|
else if (previous && cur.nextInset() && cur.nextInset()->lyxCode() == SEPARATOR_CODE)
|
|
|
|
lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK, "inverse ignoresep"));
|
2014-01-27 07:01:24 +00:00
|
|
|
if (outer) {
|
|
|
|
while (cur.paragraph().params().depth() > split_depth)
|
|
|
|
lyx::dispatch(FuncRequest(LFUN_DEPTH_DECREMENT));
|
|
|
|
}
|
Fix bugs #8546 and #9055, and introduce new separator inset.
The algorithm used for breaking a paragraph in LaTeX export is changed
for avoiding spurious blank lines causing too much vertical space.
This change is tied to the introduction of a new inset (with two
different specializations) helping in either outputing LaTeX paragraph
breaks or separating environments in LyX. Both of the above goals were
previously achieved by the ---Separator--- layout and can now be
accomplished by the new inset in a more natural way. As an example,
after leaving an environment by hitting the Return key for two times,
a third return automatically inserts a parbreak inset, which is
equivalent to the old separator layout, i.e., it also introduces a
blank line in the output. If this blank line is not wanted, the
parbreak separator can be changed to a plain separator by a right
click of the mouse. Of course, an environment can still be separated
by the following one by using the Alt+P+Return shortcut (or the
corresponding menu key), but now the plain separator inset is used
instead of the old separator layout, such that no blank line occurs in
the LaTeX output.
Old documents are converted such that the LaTeX output remains unchanged.
As a result of this conversion, the old separator layout is replaced by
the new parbreak inset, which may also appear in places where the old
algorithm was introducing blank lines while the new one is not.
Note that not all blank lines were actually affecting the LaTeX output,
because a blank line is simply ignored by the TeX engine when it occurs
in the so called "vertical mode" (e.g., after an alignment environment).
The old ---Separator--- layout is now gone and old layout files using it
are also automatically converted.
Round trip conversions between old and new format should leave a document
unchanged. This means that the new behavior about paragraph breaking is
not "carried back" to the old format. Indeed, this would need introducing
special LaTeX commands in ERT that would accumulate in roundtrip
conversions, horribly cluttering the document. So, when converting a
modified document to old formats, the LaTeX output may slightly differ in
vertical spacing if the document is processed by an old version of LyX.
In other words, forward compatibility is guaranteed, but not backwards.
2014-05-10 21:25:11 +00:00
|
|
|
DocumentClass const & tc = bv->buffer().params().documentClass();
|
2018-01-01 11:34:39 +00:00
|
|
|
lyx::dispatch(FuncRequest(LFUN_LAYOUT, from_ascii("\"") + tc.plainLayout().name()
|
|
|
|
+ from_ascii("\" ignoreautonests")));
|
Fix bugs #8546 and #9055, and introduce new separator inset.
The algorithm used for breaking a paragraph in LaTeX export is changed
for avoiding spurious blank lines causing too much vertical space.
This change is tied to the introduction of a new inset (with two
different specializations) helping in either outputing LaTeX paragraph
breaks or separating environments in LyX. Both of the above goals were
previously achieved by the ---Separator--- layout and can now be
accomplished by the new inset in a more natural way. As an example,
after leaving an environment by hitting the Return key for two times,
a third return automatically inserts a parbreak inset, which is
equivalent to the old separator layout, i.e., it also introduces a
blank line in the output. If this blank line is not wanted, the
parbreak separator can be changed to a plain separator by a right
click of the mouse. Of course, an environment can still be separated
by the following one by using the Alt+P+Return shortcut (or the
corresponding menu key), but now the plain separator inset is used
instead of the old separator layout, such that no blank line occurs in
the LaTeX output.
Old documents are converted such that the LaTeX output remains unchanged.
As a result of this conversion, the old separator layout is replaced by
the new parbreak inset, which may also appear in places where the old
algorithm was introducing blank lines while the new one is not.
Note that not all blank lines were actually affecting the LaTeX output,
because a blank line is simply ignored by the TeX engine when it occurs
in the so called "vertical mode" (e.g., after an alignment environment).
The old ---Separator--- layout is now gone and old layout files using it
are also automatically converted.
Round trip conversions between old and new format should leave a document
unchanged. This means that the new behavior about paragraph breaking is
not "carried back" to the old format. Indeed, this would need introducing
special LaTeX commands in ERT that would accumulate in roundtrip
conversions, horribly cluttering the document. So, when converting a
modified document to old formats, the LaTeX output may slightly differ in
vertical spacing if the document is processed by an old version of LyX.
In other words, forward compatibility is guaranteed, but not backwards.
2014-05-10 21:25:11 +00:00
|
|
|
lyx::dispatch(FuncRequest(LFUN_SEPARATOR_INSERT, "plain"));
|
2018-01-01 11:34:39 +00:00
|
|
|
if (before) {
|
|
|
|
cur.backwardPos();
|
|
|
|
lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK, "inverse ignoresep"));
|
|
|
|
while (cur.paragraph().params().depth() < split_depth)
|
|
|
|
lyx::dispatch(FuncRequest(LFUN_DEPTH_INCREMENT));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK, "inverse"));
|
2012-12-24 10:22:23 +00:00
|
|
|
lyx::dispatch(FuncRequest(LFUN_LAYOUT, layout));
|
2018-01-01 11:34:39 +00:00
|
|
|
if ((outer || normal) && nextpar_depth > 0) {
|
|
|
|
// restore nesting of following paragraph
|
|
|
|
DocIterator scur = cur;
|
2018-01-13 08:59:09 +00:00
|
|
|
depth_type const max_depth = cur.paragraph().params().depth() + 1;
|
2018-01-01 11:34:39 +00:00
|
|
|
cur.forwardPar();
|
2018-01-13 08:59:09 +00:00
|
|
|
while (cur.paragraph().params().depth() < min(nextpar_depth, max_depth))
|
2018-01-01 11:34:39 +00:00
|
|
|
lyx::dispatch(FuncRequest(LFUN_DEPTH_INCREMENT));
|
|
|
|
cur.setCursor(scur);
|
|
|
|
}
|
2012-12-23 17:57:32 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2007-01-03 07:30:50 +00:00
|
|
|
case LFUN_CLIPBOARD_PASTE:
|
2012-06-07 16:14:17 +00:00
|
|
|
cap::replaceSelection(cur);
|
2008-02-03 10:43:03 +00:00
|
|
|
pasteClipboardText(cur, bv->buffer().errorList("Paste"),
|
2007-05-28 22:27:45 +00:00
|
|
|
cmd.argument() == "paragraph");
|
2007-08-21 13:03:55 +00:00
|
|
|
bv->buffer().errors("Paste");
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2011-10-29 15:42:01 +00:00
|
|
|
case LFUN_CLIPBOARD_PASTE_SIMPLE:
|
2012-06-07 16:14:17 +00:00
|
|
|
cap::replaceSelection(cur);
|
2011-10-29 15:42:01 +00:00
|
|
|
pasteSimpleText(cur, cmd.argument() == "paragraph");
|
|
|
|
break;
|
|
|
|
|
2007-01-03 07:30:50 +00:00
|
|
|
case LFUN_PRIMARY_SELECTION_PASTE:
|
2012-06-07 16:14:17 +00:00
|
|
|
cap::replaceSelection(cur);
|
2007-01-06 15:33:07 +00:00
|
|
|
pasteString(cur, theSelection().get(),
|
2007-05-28 22:27:45 +00:00
|
|
|
cmd.argument() == "paragraph");
|
Split clipboard and X selection
* src/LyXAction.C
(LyXAction::init): handle new LFUN_CLIPBOARD_PASTE
* src/insets/insettabular.C
(InsetTabular::doDispatch): ditto
* src/insets/insetbox.C
(InsetBox::doDispatch): ditto
* src/insets/insetert.C
(InsetERT::doDispatch): ditto
(InsetERT::getStatus): ditto
* src/insets/insetcharstyle.C
(InsetCharStyle::doDispatch): ditto
* src/BufferView_pimpl.C
(BufferView::Pimpl::selectionRequest): stuff selection, not clipboard
* src/mathed/math_nestinset.C
(MathNestInset::lfunMousePress): get stuff selection, not clipboard
(MathNestInset::lfunMouseRelease): clipboard -> selection in
commented code
* src/CutAndPaste.C
(cutSelection): ditto
* src/frontends/{qt3,gtk}/GuiImplementation.C
(GuiImplementation::newWorkArea): create new selection, not clipboard,
since the clipboard is now an object
(GuiImplementation::destroyWorkArea): destroy selection, not clipboard
* src/frontends/{qt4,qt3,gtk}/GuiSelection.h: new, copied from
GuiClipboard.h
* src/frontends/{qt4,qt3,gtk}/GuiSelection.C: new, copied from
GuiClipboard.C
* src/frontends/{qt3,gtk}/GuiImplementation.h
(selection): new accessor for selection_
(selection_): new, the global selection object
* src/frontends/{qt4,qt3,gtk}/Makefile.am: add GuiSelection.C and
GuiSelection.h
* src/frontends/{qt4,qt3,gtk}/GuiClipboard.C
(GuiClipboard::get): return clipboard, not selection
(GuiClipboard::put): stuff clipboard, not selection
* src/frontends/{qt4,qt3,gtk}/GuiClipboard.h
(haveSelection): remove (this is now in GuiSelection)
* src/frontends/{qt3,gtk}/GuiClipboard.h
(old_work_area_): remove, since it is not needed anymore
* src/frontends/gtk/ghelpers.C
(getGTKStockIcon): handle LFUN_CLIPBOARD_PASTE
* src/frontends/Clipboard.h
(haveSelection): remove (this is now in Selection)
* src/frontends/qt4/GuiImplementation.[Ch]
(GuiImplementation::selection): new accessor for selection_
* src/frontends/Gui.h
(selection): New accessor for the global selection object
* src/frontends/Selection.h; new, copied from Clipboard.h
* src/frontends/Makefile.am: add Selection.h
* src/text3.C
(various): s/clipboard().haveSelection/selection().haveSelection/
(LyXText::dispatch): handle LFUN_CLIPBOARD_PASTE
(LyXText::getStatus): ditto
* src/lfuns.h: new lfun LFUN_CLIPBOARD_PASTE
* lib/ui/stdmenus.ui: add new lfun LFUN_CLIPBOARD_PASTE
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@14408 a592a061-630c-0410-9148-cb99ea01b6c8
2006-07-10 11:32:25 +00:00
|
|
|
break;
|
|
|
|
|
2009-01-14 14:24:59 +00:00
|
|
|
case LFUN_SELECTION_PASTE:
|
|
|
|
// Copy the selection buffer to the clipboard stack,
|
|
|
|
// because we want it to appear in the "Edit->Paste
|
|
|
|
// recent" menu.
|
2012-06-07 16:14:17 +00:00
|
|
|
cap::replaceSelection(cur);
|
2009-01-14 14:24:59 +00:00
|
|
|
cap::copySelectionToStack();
|
|
|
|
cap::pasteSelection(bv->cursor(), bv->buffer().errorList("Paste"));
|
|
|
|
bv->buffer().errors("Paste");
|
|
|
|
break;
|
|
|
|
|
2006-10-22 18:47:19 +00:00
|
|
|
case LFUN_UNICODE_INSERT: {
|
|
|
|
if (cmd.argument().empty())
|
|
|
|
break;
|
|
|
|
docstring hexstring = cmd.argument();
|
2007-12-12 19:57:42 +00:00
|
|
|
if (isHex(hexstring)) {
|
|
|
|
char_type c = hexToInt(hexstring);
|
2007-06-22 16:27:37 +00:00
|
|
|
if (c >= 32 && c < 0x10ffff) {
|
2006-10-22 18:47:19 +00:00
|
|
|
lyxerr << "Inserting c: " << c << endl;
|
|
|
|
docstring s = docstring(1, c);
|
|
|
|
lyx::dispatch(FuncRequest(LFUN_SELF_INSERT, s));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2007-05-28 22:27:45 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_QUOTE_INSERT: {
|
2011-01-02 12:07:33 +00:00
|
|
|
cap::replaceSelection(cur);
|
2013-01-21 13:49:45 +00:00
|
|
|
cur.recordUndo();
|
2011-01-02 12:07:33 +00:00
|
|
|
|
|
|
|
Paragraph const & par = cur.paragraph();
|
2006-10-21 00:16:43 +00:00
|
|
|
pos_type pos = cur.pos();
|
2013-01-21 13:49:45 +00:00
|
|
|
// Ignore deleted text before cursor
|
|
|
|
while (pos > 0 && par.isDeleted(pos - 1))
|
|
|
|
--pos;
|
2011-01-02 12:07:33 +00:00
|
|
|
|
2016-12-27 11:06:54 +00:00
|
|
|
bool const inner = (cmd.getArg(0) == "single" || cmd.getArg(0) == "inner");
|
|
|
|
|
|
|
|
// Guess quote side.
|
|
|
|
// A space triggers an opening quote. This is passed if the preceding
|
|
|
|
// char/inset is a space or at paragraph start.
|
2016-12-10 10:53:42 +00:00
|
|
|
char_type c = ' ';
|
2016-12-27 11:06:54 +00:00
|
|
|
if (pos > 0 && !par.isSpace(pos - 1)) {
|
|
|
|
if (cur.prevInset() && cur.prevInset()->lyxCode() == QUOTE_CODE) {
|
|
|
|
// If an opening double quotation mark precedes, and this
|
|
|
|
// is a single quote, make it opening as well
|
|
|
|
InsetQuotes & ins =
|
|
|
|
static_cast<InsetQuotes &>(*cur.prevInset());
|
|
|
|
string const type = ins.getType();
|
|
|
|
if (!suffixIs(type, "ld") || !inner)
|
|
|
|
c = par.getChar(pos - 1);
|
|
|
|
}
|
|
|
|
else if (!cur.prevInset()
|
|
|
|
|| (cur.prevInset() && cur.prevInset()->isChar()))
|
|
|
|
// If a char precedes, pass that and let InsetQuote decide
|
|
|
|
c = par.getChar(pos - 1);
|
|
|
|
else {
|
|
|
|
while (pos > 0) {
|
|
|
|
if (par.getInset(pos - 1)
|
|
|
|
&& !par.getInset(pos - 1)->isPartOfTextSequence()) {
|
|
|
|
// skip "invisible" insets
|
|
|
|
--pos;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
c = par.getChar(pos - 1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
InsetQuotesParams::QuoteLevel const quote_level = inner
|
2016-12-24 13:27:00 +00:00
|
|
|
? InsetQuotesParams::SecondaryQuotes : InsetQuotesParams::PrimaryQuotes;
|
2016-12-20 16:55:43 +00:00
|
|
|
cur.insert(new InsetQuotes(cur.buffer(), c, quote_level, cmd.getArg(1), cmd.getArg(2)));
|
2016-12-10 10:53:42 +00:00
|
|
|
cur.buffer()->updateBuffer();
|
|
|
|
cur.posForward();
|
2002-08-27 13:17:22 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2007-08-11 22:37:09 +00:00
|
|
|
case LFUN_DATE_INSERT: {
|
|
|
|
string const format = cmd.argument().empty()
|
|
|
|
? lyxrc.date_insert_format : to_utf8(cmd.argument());
|
|
|
|
string const time = formatted_time(current_time(), format);
|
|
|
|
lyx::dispatch(FuncRequest(LFUN_SELF_INSERT, time));
|
2002-08-27 13:39:27 +00:00
|
|
|
break;
|
2007-08-11 22:37:09 +00:00
|
|
|
}
|
2002-08-27 13:39:27 +00:00
|
|
|
|
2002-08-28 10:45:38 +00:00
|
|
|
case LFUN_MOUSE_TRIPLE:
|
2004-02-06 16:50:29 +00:00
|
|
|
if (cmd.button() == mouse_button::button1) {
|
2009-05-14 12:35:04 +00:00
|
|
|
tm->cursorHome(cur);
|
2004-01-20 14:25:24 +00:00
|
|
|
cur.resetAnchor();
|
2009-05-14 12:35:04 +00:00
|
|
|
tm->cursorEnd(cur);
|
2004-01-20 14:25:24 +00:00
|
|
|
cur.setSelection();
|
2005-04-20 10:47:15 +00:00
|
|
|
bv->cursor() = cur;
|
2002-08-28 10:45:38 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LFUN_MOUSE_DOUBLE:
|
2004-02-06 16:50:29 +00:00
|
|
|
if (cmd.button() == mouse_button::button1) {
|
2014-06-13 13:43:26 +00:00
|
|
|
selectWord(cur, WHOLE_WORD);
|
2005-04-20 10:47:15 +00:00
|
|
|
bv->cursor() = cur;
|
2002-08-28 10:45:38 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
// Single-click on work area
|
2009-12-18 14:18:10 +00:00
|
|
|
case LFUN_MOUSE_PRESS: {
|
2008-03-25 10:54:38 +00:00
|
|
|
// We are not marking a selection with the keyboard in any case.
|
2009-12-18 14:18:10 +00:00
|
|
|
Cursor & bvcur = cur.bv().cursor();
|
|
|
|
bvcur.setMark(false);
|
2008-03-25 10:54:38 +00:00
|
|
|
switch (cmd.button()) {
|
|
|
|
case mouse_button::button1:
|
2016-08-29 10:03:33 +00:00
|
|
|
if (!bvcur.selection())
|
|
|
|
// Set the cursor
|
|
|
|
bvcur.resetAnchor();
|
2016-06-20 19:10:14 +00:00
|
|
|
if (!bv->mouseSetCursor(cur, cmd.modifier() == ShiftModifier))
|
|
|
|
cur.screenUpdateFlags(Update::SinglePar | Update::FitCursor);
|
2009-12-18 14:18:10 +00:00
|
|
|
if (bvcur.wordSelection())
|
|
|
|
selectWord(bvcur, WHOLE_WORD);
|
2008-10-13 11:25:37 +00:00
|
|
|
break;
|
2008-03-25 10:54:38 +00:00
|
|
|
|
|
|
|
case mouse_button::button2:
|
2015-02-08 16:41:28 +00:00
|
|
|
if (lyxrc.mouse_middlebutton_paste) {
|
|
|
|
// Middle mouse pasting.
|
|
|
|
bv->mouseSetCursor(cur);
|
|
|
|
lyx::dispatch(
|
|
|
|
FuncRequest(LFUN_COMMAND_ALTERNATIVES,
|
|
|
|
"selection-paste ; primary-selection-paste paragraph"));
|
|
|
|
}
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.noScreenUpdate();
|
2008-03-25 10:54:38 +00:00
|
|
|
break;
|
2004-04-07 08:07:26 +00:00
|
|
|
|
2008-08-12 10:17:31 +00:00
|
|
|
case mouse_button::button3: {
|
|
|
|
// Don't do anything if we right-click a
|
|
|
|
// selection, a context menu will popup.
|
|
|
|
if (bvcur.selection() && cur >= bvcur.selectionBegin()
|
2008-08-14 10:28:20 +00:00
|
|
|
&& cur < bvcur.selectionEnd()) {
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.noScreenUpdate();
|
2008-08-12 10:17:31 +00:00
|
|
|
return;
|
2008-03-25 10:54:38 +00:00
|
|
|
}
|
2008-08-12 10:17:31 +00:00
|
|
|
if (!bv->mouseSetCursor(cur, false))
|
2015-10-05 16:04:12 +00:00
|
|
|
cur.screenUpdateFlags(Update::FitCursor);
|
2008-10-13 11:25:37 +00:00
|
|
|
break;
|
2008-08-12 10:17:31 +00:00
|
|
|
}
|
|
|
|
|
2008-03-26 18:53:18 +00:00
|
|
|
default:
|
|
|
|
break;
|
2008-03-25 21:44:30 +00:00
|
|
|
} // switch (cmd.button())
|
|
|
|
break;
|
2009-12-18 14:18:10 +00:00
|
|
|
}
|
2004-08-14 20:34:46 +00:00
|
|
|
case LFUN_MOUSE_MOTION: {
|
2008-03-25 10:54:38 +00:00
|
|
|
// Mouse motion with right or middle mouse do nothing for now.
|
|
|
|
if (cmd.button() != mouse_button::button1) {
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.noScreenUpdate();
|
2008-03-25 10:54:38 +00:00
|
|
|
return;
|
|
|
|
}
|
2004-08-14 20:34:46 +00:00
|
|
|
// ignore motions deeper nested than the real anchor
|
2007-04-26 14:56:30 +00:00
|
|
|
Cursor & bvcur = cur.bv().cursor();
|
2010-04-15 18:16:07 +00:00
|
|
|
if (!bvcur.realAnchor().hasPart(cur)) {
|
2007-11-17 18:17:19 +00:00
|
|
|
cur.undispatched();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
CursorSlice old = bvcur.top();
|
|
|
|
|
|
|
|
int const wh = bv->workHeight();
|
2010-04-09 19:00:42 +00:00
|
|
|
int const y = max(0, min(wh - 1, cmd.y()));
|
2007-11-17 18:17:19 +00:00
|
|
|
|
2017-04-01 11:09:23 +00:00
|
|
|
tm->setCursorFromCoordinates(cur, cmd.x(), y);
|
2010-04-09 19:00:42 +00:00
|
|
|
cur.setTargetX(cmd.x());
|
2016-04-21 21:44:14 +00:00
|
|
|
// Don't allow selecting a separator inset
|
|
|
|
if (cur.pos() && cur.paragraph().isEnvSeparator(cur.pos() - 1))
|
|
|
|
cur.posBackward();
|
2010-04-09 19:00:42 +00:00
|
|
|
if (cmd.y() >= wh)
|
2007-11-17 18:17:19 +00:00
|
|
|
lyx::dispatch(FuncRequest(LFUN_DOWN_SELECT));
|
2010-04-09 19:00:42 +00:00
|
|
|
else if (cmd.y() < 0)
|
2007-11-17 18:17:19 +00:00
|
|
|
lyx::dispatch(FuncRequest(LFUN_UP_SELECT));
|
|
|
|
// This is to allow jumping over large insets
|
|
|
|
if (cur.top() == old) {
|
2010-04-09 19:00:42 +00:00
|
|
|
if (cmd.y() >= wh)
|
2006-12-20 14:17:50 +00:00
|
|
|
lyx::dispatch(FuncRequest(LFUN_DOWN_SELECT));
|
2010-04-09 19:00:42 +00:00
|
|
|
else if (cmd.y() < 0)
|
2006-12-20 14:17:50 +00:00
|
|
|
lyx::dispatch(FuncRequest(LFUN_UP_SELECT));
|
2007-11-17 18:17:19 +00:00
|
|
|
}
|
2008-03-25 10:54:38 +00:00
|
|
|
// We continue with our existing selection or start a new one, so don't
|
|
|
|
// reset the anchor.
|
|
|
|
bvcur.setCursor(cur);
|
2016-02-28 16:36:29 +00:00
|
|
|
bvcur.selection(true);
|
2017-10-11 09:56:09 +00:00
|
|
|
bvcur.setCurrentFont();
|
2008-03-25 10:54:38 +00:00
|
|
|
if (cur.top() == old) {
|
|
|
|
// We didn't move one iota, so no need to update the screen.
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.screenUpdateFlags(Update::SinglePar | Update::FitCursor);
|
|
|
|
//cur.noScreenUpdate();
|
2008-03-25 10:54:38 +00:00
|
|
|
return;
|
2007-11-17 18:17:19 +00:00
|
|
|
}
|
2004-08-14 20:34:46 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2008-03-25 10:54:38 +00:00
|
|
|
case LFUN_MOUSE_RELEASE:
|
|
|
|
switch (cmd.button()) {
|
|
|
|
case mouse_button::button1:
|
|
|
|
// Cursor was set at LFUN_MOUSE_PRESS or LFUN_MOUSE_MOTION time.
|
|
|
|
// If there is a new selection, update persistent selection;
|
|
|
|
// otherwise, single click does not clear persistent selection
|
|
|
|
// buffer.
|
2007-02-02 03:10:15 +00:00
|
|
|
if (cur.selection()) {
|
2008-08-13 15:22:41 +00:00
|
|
|
// Finish selection. If double click,
|
|
|
|
// cur is moved to the end of word by
|
|
|
|
// selectWord but bvcur is current
|
|
|
|
// mouse position.
|
|
|
|
cur.bv().cursor().setSelection();
|
2008-09-13 22:59:09 +00:00
|
|
|
// We might have removed an empty but drawn selection
|
|
|
|
// (probably a margin)
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.screenUpdateFlags(Update::SinglePar | Update::FitCursor);
|
2008-09-13 22:59:09 +00:00
|
|
|
} else
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.noScreenUpdate();
|
2008-03-25 10:54:38 +00:00
|
|
|
// FIXME: We could try to handle drag and drop of selection here.
|
|
|
|
return;
|
|
|
|
|
|
|
|
case mouse_button::button2:
|
|
|
|
// Middle mouse pasting is handled at mouse press time,
|
|
|
|
// see LFUN_MOUSE_PRESS.
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.noScreenUpdate();
|
2008-03-25 10:54:38 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
case mouse_button::button3:
|
|
|
|
// Cursor was set at LFUN_MOUSE_PRESS time.
|
|
|
|
// FIXME: If there is a selection we could try to handle a special
|
|
|
|
// drag & drop context menu.
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.noScreenUpdate();
|
2008-03-25 10:54:38 +00:00
|
|
|
return;
|
|
|
|
|
2008-05-22 13:52:18 +00:00
|
|
|
case mouse_button::none:
|
|
|
|
case mouse_button::button4:
|
|
|
|
case mouse_button::button5:
|
|
|
|
break;
|
2008-03-25 10:54:38 +00:00
|
|
|
} // switch (cmd.button())
|
2002-08-28 10:45:38 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_SELF_INSERT: {
|
2006-09-01 15:41:38 +00:00
|
|
|
if (cmd.argument().empty())
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
2002-08-20 13:00:25 +00:00
|
|
|
|
|
|
|
// Automatically delete the currently selected
|
|
|
|
// text and replace it with what is being
|
|
|
|
// typed in now. Depends on lyxrc settings
|
|
|
|
// "auto_region_delete", which defaults to
|
|
|
|
// true (on).
|
|
|
|
|
2007-11-17 11:27:03 +00:00
|
|
|
if (lyxrc.auto_region_delete && cur.selection())
|
2007-07-09 10:32:28 +00:00
|
|
|
cutSelection(cur, false, false);
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2004-01-20 14:25:24 +00:00
|
|
|
cur.clearSelection();
|
2005-04-26 11:12:20 +00:00
|
|
|
|
2006-09-01 15:41:38 +00:00
|
|
|
docstring::const_iterator cit = cmd.argument().begin();
|
2008-10-19 09:23:46 +00:00
|
|
|
docstring::const_iterator const end = cmd.argument().end();
|
2002-08-20 13:00:25 +00:00
|
|
|
for (; cit != end; ++cit)
|
2007-06-11 22:05:44 +00:00
|
|
|
bv->translateAndInsert(*cit, this, cur);
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2004-01-20 14:25:24 +00:00
|
|
|
cur.resetAnchor();
|
|
|
|
moveCursor(cur, false);
|
2011-04-01 05:49:04 +00:00
|
|
|
cur.markNewWordPosition();
|
2009-02-13 13:46:08 +00:00
|
|
|
bv->bookmarkEditPosition();
|
2002-08-20 15:26:52 +00:00
|
|
|
break;
|
2002-08-20 13:00:25 +00:00
|
|
|
}
|
|
|
|
|
2014-02-11 10:00:20 +00:00
|
|
|
case LFUN_HREF_INSERT: {
|
2014-02-23 16:20:47 +00:00
|
|
|
docstring content = cmd.argument();
|
2016-12-29 08:17:53 +00:00
|
|
|
if (content.empty() && cur.selection())
|
2007-07-30 10:33:43 +00:00
|
|
|
content = cur.selectionAsString(false);
|
2014-02-23 16:20:47 +00:00
|
|
|
|
|
|
|
InsetCommandParams p(HYPERLINK_CODE);
|
|
|
|
if (!content.empty()){
|
|
|
|
// if it looks like a link, we'll put it as target,
|
|
|
|
// otherwise as name (bug #8792).
|
|
|
|
|
|
|
|
// We can't do:
|
|
|
|
// regex_match(to_utf8(content), matches, link_re)
|
|
|
|
// because smatch stores pointers to the substrings rather
|
|
|
|
// than making copies of them. And those pointers become
|
|
|
|
// invalid after regex_match returns, since it is then
|
|
|
|
// being given a temporary object. (Thanks to Georg for
|
|
|
|
// figuring that out.)
|
2014-02-23 17:04:56 +00:00
|
|
|
regex const link_re("^([a-z]+):.*");
|
2014-02-23 16:20:47 +00:00
|
|
|
smatch matches;
|
2014-02-23 17:04:56 +00:00
|
|
|
string const c = to_utf8(lowercase(content));
|
2014-02-23 16:20:47 +00:00
|
|
|
|
2014-02-23 17:04:56 +00:00
|
|
|
if (c.substr(0,7) == "mailto:") {
|
2014-02-23 16:20:47 +00:00
|
|
|
p["target"] = content;
|
|
|
|
p["type"] = from_ascii("mailto:");
|
|
|
|
} else if (regex_match(c, matches, link_re)) {
|
|
|
|
p["target"] = content;
|
|
|
|
string protocol = matches.str(1);
|
|
|
|
if (protocol == "file")
|
|
|
|
p["type"] = from_ascii("file:");
|
|
|
|
} else
|
|
|
|
p["name"] = content;
|
|
|
|
}
|
2010-10-29 00:25:28 +00:00
|
|
|
string const data = InsetCommand::params2string(p);
|
2014-02-23 16:20:47 +00:00
|
|
|
|
|
|
|
// we need to have a target. if we already have one, then
|
|
|
|
// that gets used at the default for the name, too, which
|
|
|
|
// is probably what is wanted.
|
2007-07-30 10:33:43 +00:00
|
|
|
if (p["target"].empty()) {
|
2007-11-18 00:39:15 +00:00
|
|
|
bv->showDialog("href", data);
|
2007-07-30 10:33:43 +00:00
|
|
|
} else {
|
|
|
|
FuncRequest fr(LFUN_INSET_INSERT, data);
|
|
|
|
dispatch(cur, fr);
|
|
|
|
}
|
2002-08-29 13:41:58 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_LABEL_INSERT: {
|
2007-10-19 17:22:55 +00:00
|
|
|
InsetCommandParams p(LABEL_CODE);
|
2004-04-19 02:39:05 +00:00
|
|
|
// Try to generate a valid label
|
Rework InsetCommandParams interface and file storage
* src/insets/insetcommandparams.[Ch]:
(operator[]): New, access a parameter
(clear): New, clear all parameters
(info_): New, stire info about this command
(cmdname): Rename to name_
(contents, options, sec_options): Replace with params_. Parameters
are now stored as docstring.
(findInfo): New factor for command info for all commands
(read, write): Use new syntax
(parameter set and get methods): reimplemenmt for new parameter storage
* src/insets/insetcommand.h
(getParam): New, get a parameter
(setParam): New, set a parameter
(parameter set and get methods): Adjust to InsetCommandParams changes
* src/insets/insetbibitem.[Ch]
(write): Remove, not needed anymore
(directWrite): ditto
* src/insets/insetbibitem.C
(InsetBibitem::read): Use InsetCommand::read
* src/insets/insetref.C
(InsetRef::latex): Use new InsetCommandParams interface
* src/mathed/InsetMathHull.C
(InsetMathHull::doDispatch): ditto
* src/text3.C
(LyXText::dispatch): ditto
* src/factory.C
(createInset): Create InsetCommandParams with command name
(readInset): ditto
(readInset): Remove error message for bibitem, since bibitem is
now a normal command inset
* src/buffer.C: Bump file format number
* src/frontends/controllers/ControlCommand.[Ch]
(ControlCommand): take an additional command name parameter
* src/text.C
(readParToken): Remove code for \bibitem
* lib/lyx2lyx/LyX.py: Bump latest file format number
* lib/lyx2lyx/lyx_1_5.py
(convert_bibitem, convert_commandparams): new, convert to new format
(revert_commandparams): new, convert to old format
* development/FORMAT: document new format
* many other files: Adjust to the changes above
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@15357 a592a061-630c-0410-9148-cb99ea01b6c8
2006-10-17 21:07:16 +00:00
|
|
|
p["name"] = (cmd.argument().empty()) ?
|
2006-11-11 11:27:47 +00:00
|
|
|
cur.getPossibleLabel() :
|
Rework InsetCommandParams interface and file storage
* src/insets/insetcommandparams.[Ch]:
(operator[]): New, access a parameter
(clear): New, clear all parameters
(info_): New, stire info about this command
(cmdname): Rename to name_
(contents, options, sec_options): Replace with params_. Parameters
are now stored as docstring.
(findInfo): New factor for command info for all commands
(read, write): Use new syntax
(parameter set and get methods): reimplemenmt for new parameter storage
* src/insets/insetcommand.h
(getParam): New, get a parameter
(setParam): New, set a parameter
(parameter set and get methods): Adjust to InsetCommandParams changes
* src/insets/insetbibitem.[Ch]
(write): Remove, not needed anymore
(directWrite): ditto
* src/insets/insetbibitem.C
(InsetBibitem::read): Use InsetCommand::read
* src/insets/insetref.C
(InsetRef::latex): Use new InsetCommandParams interface
* src/mathed/InsetMathHull.C
(InsetMathHull::doDispatch): ditto
* src/text3.C
(LyXText::dispatch): ditto
* src/factory.C
(createInset): Create InsetCommandParams with command name
(readInset): ditto
(readInset): Remove error message for bibitem, since bibitem is
now a normal command inset
* src/buffer.C: Bump file format number
* src/frontends/controllers/ControlCommand.[Ch]
(ControlCommand): take an additional command name parameter
* src/text.C
(readParToken): Remove code for \bibitem
* lib/lyx2lyx/LyX.py: Bump latest file format number
* lib/lyx2lyx/lyx_1_5.py
(convert_bibitem, convert_commandparams): new, convert to new format
(revert_commandparams): new, convert to old format
* development/FORMAT: document new format
* many other files: Adjust to the changes above
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@15357 a592a061-630c-0410-9148-cb99ea01b6c8
2006-10-17 21:07:16 +00:00
|
|
|
cmd.argument();
|
2010-10-29 00:25:28 +00:00
|
|
|
string const data = InsetCommand::params2string(p);
|
2004-04-19 02:39:05 +00:00
|
|
|
|
2006-09-01 15:41:38 +00:00
|
|
|
if (cmd.argument().empty()) {
|
2007-11-18 00:39:15 +00:00
|
|
|
bv->showDialog("label", data);
|
2004-04-19 02:39:05 +00:00
|
|
|
} else {
|
|
|
|
FuncRequest fr(LFUN_INSET_INSERT, data);
|
|
|
|
dispatch(cur, fr);
|
|
|
|
}
|
2003-11-13 20:16:34 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2007-10-11 14:52:00 +00:00
|
|
|
case LFUN_INFO_INSERT: {
|
2008-06-06 09:01:55 +00:00
|
|
|
Inset * inset;
|
2007-10-14 00:47:52 +00:00
|
|
|
if (cmd.argument().empty() && cur.selection()) {
|
2008-06-06 09:01:55 +00:00
|
|
|
// if command argument is empty use current selection as parameter.
|
2007-10-14 00:47:52 +00:00
|
|
|
docstring ds = cur.selectionAsString(false);
|
|
|
|
cutSelection(cur, true, false);
|
2008-06-06 09:01:55 +00:00
|
|
|
FuncRequest cmd0(cmd, ds);
|
2009-11-08 15:53:21 +00:00
|
|
|
inset = createInset(cur.buffer(), cmd0);
|
2008-06-06 09:01:55 +00:00
|
|
|
} else {
|
2009-11-08 15:53:21 +00:00
|
|
|
inset = createInset(cur.buffer(), cmd);
|
2007-10-14 00:47:52 +00:00
|
|
|
}
|
2008-06-06 09:01:55 +00:00
|
|
|
if (!inset)
|
|
|
|
break;
|
2009-05-09 21:02:14 +00:00
|
|
|
cur.recordUndo();
|
2007-10-11 14:52:00 +00:00
|
|
|
insertInset(cur, inset);
|
2018-01-05 18:29:45 +00:00
|
|
|
cur.forceBufferUpdate();
|
2007-11-05 19:41:16 +00:00
|
|
|
cur.posForward();
|
2007-10-11 14:52:00 +00:00
|
|
|
break;
|
|
|
|
}
|
2007-01-30 13:23:21 +00:00
|
|
|
case LFUN_CAPTION_INSERT:
|
2007-11-02 18:19:45 +00:00
|
|
|
case LFUN_FOOTNOTE_INSERT:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_NOTE_INSERT:
|
|
|
|
case LFUN_BOX_INSERT:
|
|
|
|
case LFUN_BRANCH_INSERT:
|
2009-01-30 00:56:37 +00:00
|
|
|
case LFUN_PHANTOM_INSERT:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_ERT_INSERT:
|
Add support for listings package. Two listings command \lstinline, \lstinputlisting and an environment \lstlisting are supported, along with preamble \lstset. \lstinputlisting is implemented through Include dialog, and the other two are implemented with a new inset listings, along with its dialog.
* src/LyXAction.cpp: listing-insert action
* src/insets/Inset.h,cpp: LISTINGS_CODE
* src/insets/InsetInclude.cpp: handle \lstinputlisting
* src/insets/InsetListings.h,cpp: new listings inset
* src/insets/InsetListingsParams.h,cpp: parameters from listings package
* src/insets/InsetCommandParams.h,cpp: handle lstinputlisting option
* src/Bidi.cpp: handle LISTINGS_CODE
* src/frontends/qt4/ui/TextLayoutUi.ui: update UI
* src/frontends/qt4/ui/ListingsUi.ui: new dialog
* src/frontends/qt4/ui/IncludeUi.ui: update UI
* src/frontends/qt4/QInclude.h,cpp: add lstinputlisting
* src/frontends/qt4/QDocument.h,cpp: add textedit for preamble listings_params
* src/frontends/qt4/QListings.h,cpp: new listings inset
* src/frontends/qt4/Dialogs.cpp: new listings dialog
* src/frontends/controllers/ControlInclude.h,cpp: add lstinputlisting
* src/frontends/controllers/ControlListings.h,cpp: new listings inset
* src/LyXFunc.cpp: handle LISTING_CODE
* src/Paragraph.cpp: handle LISTING_CODE
* src/factory.cpp: new listings inset
* src/CutAndPaste.cpp: handle LISTINGS_CODE
* src/LaTeXFeatures.cpp: require listings
* src/Text3.cpp: Handle LISTINGS_CODE
* src/lfuns.h: add LFUN_LISTING_INSERT
* src/Buffer.cpp: change lyx file format to 269
* src/BufferParams.h,cpp: add listings_params to preamble
* lib/lyx2lyx/LyX.py: lyx2lyx
* lib/lyx2lyx/lyx_1_5.py: lyx2lyx
* lib/ui/stdmenus.inc: new menu item (no shortcut!)
* src/insets/Makefile.am: update autotools
* src/frontends/controllers/Makefile.am
* src/frontends/qt4/Makefile.dialogs
* src/frontends/qt4/Makefile.am
* po/POTFILES.in: a few more translatable files.
* development/scons/scons_manifest.py: scons build system
* development/FORMAT: document format changes
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@18243 a592a061-630c-0410-9148-cb99ea01b6c8
2007-05-09 19:11:42 +00:00
|
|
|
case LFUN_LISTING_INSERT:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_MARGINALNOTE_INSERT:
|
2010-06-04 22:53:44 +00:00
|
|
|
case LFUN_ARGUMENT_INSERT:
|
2008-02-13 12:10:18 +00:00
|
|
|
case LFUN_INDEX_INSERT:
|
2010-03-28 13:47:50 +00:00
|
|
|
case LFUN_PREVIEW_INSERT:
|
2010-11-23 20:09:08 +00:00
|
|
|
case LFUN_SCRIPT_INSERT:
|
2012-03-06 07:54:22 +00:00
|
|
|
case LFUN_IPA_INSERT:
|
2003-01-17 09:57:50 +00:00
|
|
|
// Open the inset, and move the current selection
|
|
|
|
// inside it.
|
2004-02-13 11:05:29 +00:00
|
|
|
doInsertInset(cur, this, cmd, true, true);
|
2007-11-05 19:41:16 +00:00
|
|
|
cur.posForward();
|
2008-02-13 12:10:18 +00:00
|
|
|
// Some insets are numbered, others are shown in the outline pane so
|
|
|
|
// let's update the labels and the toc backend.
|
2010-07-09 14:37:00 +00:00
|
|
|
cur.forceBufferUpdate();
|
2003-01-17 09:57:50 +00:00
|
|
|
break;
|
|
|
|
|
2012-12-17 12:32:40 +00:00
|
|
|
case LFUN_FLEX_INSERT: {
|
|
|
|
// Open the inset, and move the current selection
|
|
|
|
// inside it.
|
|
|
|
bool const sel = cur.selection();
|
|
|
|
doInsertInset(cur, this, cmd, true, true);
|
|
|
|
// Insert auto-insert arguments
|
|
|
|
bool autoargs = false;
|
|
|
|
Layout::LaTeXArgMap args = cur.inset().getLayout().latexargs();
|
|
|
|
Layout::LaTeXArgMap::const_iterator lait = args.begin();
|
|
|
|
Layout::LaTeXArgMap::const_iterator const laend = args.end();
|
|
|
|
for (; lait != laend; ++lait) {
|
|
|
|
Layout::latexarg arg = (*lait).second;
|
|
|
|
if (arg.autoinsert) {
|
|
|
|
// The cursor might have been invalidated by the replaceSelection.
|
|
|
|
cur.buffer()->changed(true);
|
|
|
|
FuncRequest cmd(LFUN_ARGUMENT_INSERT, (*lait).first);
|
|
|
|
lyx::dispatch(cmd);
|
|
|
|
autoargs = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!autoargs) {
|
|
|
|
if (sel)
|
|
|
|
cur.leaveInset(cur.inset());
|
|
|
|
cur.posForward();
|
|
|
|
}
|
|
|
|
// Some insets are numbered, others are shown in the outline pane so
|
|
|
|
// let's update the labels and the toc backend.
|
|
|
|
cur.forceBufferUpdate();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2005-05-30 15:35:11 +00:00
|
|
|
case LFUN_TABULAR_INSERT:
|
|
|
|
// if there were no arguments, just open the dialog
|
|
|
|
if (doInsertInset(cur, this, cmd, false, true))
|
2007-11-05 19:41:16 +00:00
|
|
|
cur.posForward();
|
2005-05-30 15:35:11 +00:00
|
|
|
else
|
2006-09-19 13:36:20 +00:00
|
|
|
bv->showDialog("tabularcreate");
|
2005-05-30 15:35:11 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FLOAT_INSERT:
|
|
|
|
case LFUN_FLOAT_WIDE_INSERT:
|
2007-02-01 09:22:03 +00:00
|
|
|
case LFUN_WRAP_INSERT: {
|
2012-01-21 07:02:09 +00:00
|
|
|
// will some content be moved into the inset?
|
|
|
|
bool const content = cur.selection();
|
|
|
|
// does the content consist of multiple paragraphs?
|
|
|
|
bool const singlepar = (cur.selBegin().pit() == cur.selEnd().pit());
|
2007-02-09 10:57:23 +00:00
|
|
|
|
2005-04-14 10:19:39 +00:00
|
|
|
doInsertInset(cur, this, cmd, true, true);
|
2007-11-05 19:41:16 +00:00
|
|
|
cur.posForward();
|
2008-10-24 20:56:38 +00:00
|
|
|
|
2012-01-21 07:02:09 +00:00
|
|
|
// If some single-par content is moved into the inset,
|
|
|
|
// doInsertInset puts the cursor outside the inset.
|
|
|
|
// To insert the caption we put it back into the inset.
|
|
|
|
// FIXME cleanup doInsertInset to avoid such dances!
|
|
|
|
if (content && singlepar)
|
2008-10-24 20:56:38 +00:00
|
|
|
cur.backwardPos();
|
|
|
|
|
2007-02-01 09:22:03 +00:00
|
|
|
ParagraphList & pars = cur.text()->paragraphs();
|
2007-02-09 10:57:23 +00:00
|
|
|
|
2008-02-28 01:42:02 +00:00
|
|
|
DocumentClass const & tclass = bv->buffer().params().documentClass();
|
2007-02-09 10:57:23 +00:00
|
|
|
|
|
|
|
// add a separate paragraph for the caption inset
|
|
|
|
pars.push_back(Paragraph());
|
2009-08-09 17:01:04 +00:00
|
|
|
pars.back().setInsetOwner(&cur.text()->inset());
|
2008-07-10 17:41:52 +00:00
|
|
|
pars.back().setPlainOrDefaultLayout(tclass);
|
2007-02-09 10:57:23 +00:00
|
|
|
int cap_pit = pars.size() - 1;
|
|
|
|
|
|
|
|
// if an empty inset was created, we create an additional empty
|
|
|
|
// paragraph at the bottom so that the user can choose where to put
|
|
|
|
// the graphics (or table).
|
|
|
|
if (!content) {
|
|
|
|
pars.push_back(Paragraph());
|
2009-08-09 17:01:04 +00:00
|
|
|
pars.back().setInsetOwner(&cur.text()->inset());
|
2008-07-10 17:41:52 +00:00
|
|
|
pars.back().setPlainOrDefaultLayout(tclass);
|
2007-02-09 10:57:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// reposition the cursor to the caption
|
|
|
|
cur.pit() = cap_pit;
|
2007-02-01 09:22:03 +00:00
|
|
|
cur.pos() = 0;
|
2007-08-27 09:03:18 +00:00
|
|
|
// FIXME: This Text/Cursor dispatch handling is a mess!
|
|
|
|
// We cannot use Cursor::dispatch here it needs access to up to
|
|
|
|
// date metrics.
|
2007-08-27 13:12:51 +00:00
|
|
|
FuncRequest cmd_caption(LFUN_CAPTION_INSERT);
|
2008-10-24 20:56:38 +00:00
|
|
|
doInsertInset(cur, cur.text(), cmd_caption, true, false);
|
2010-07-09 14:37:00 +00:00
|
|
|
cur.forceBufferUpdate();
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.screenUpdateFlags(Update::Force);
|
2007-02-01 09:22:03 +00:00
|
|
|
// FIXME: When leaving the Float (or Wrap) inset we should
|
2007-02-01 16:23:24 +00:00
|
|
|
// delete any empty paragraph left above or below the
|
2007-02-01 09:22:03 +00:00
|
|
|
// caption.
|
2005-04-14 10:19:39 +00:00
|
|
|
break;
|
2007-02-01 09:22:03 +00:00
|
|
|
}
|
2005-04-14 10:19:39 +00:00
|
|
|
|
2006-11-04 17:55:36 +00:00
|
|
|
case LFUN_NOMENCL_INSERT: {
|
2008-08-09 03:11:53 +00:00
|
|
|
InsetCommandParams p(NOMENCL_CODE);
|
2008-08-09 16:15:49 +00:00
|
|
|
if (cmd.argument().empty())
|
2008-08-09 15:26:06 +00:00
|
|
|
p["symbol"] = bv->cursor().innerText()->getStringToIndex(bv->cursor());
|
2008-08-09 16:15:49 +00:00
|
|
|
else
|
|
|
|
p["symbol"] = cmd.argument();
|
2010-10-29 00:25:28 +00:00
|
|
|
string const data = InsetCommand::params2string(p);
|
2008-10-13 11:25:37 +00:00
|
|
|
bv->showDialog("nomenclature", data);
|
2003-01-17 09:57:50 +00:00
|
|
|
break;
|
2005-11-30 15:51:12 +00:00
|
|
|
}
|
2003-01-17 09:57:50 +00:00
|
|
|
|
2009-04-16 07:29:01 +00:00
|
|
|
case LFUN_INDEX_PRINT: {
|
|
|
|
InsetCommandParams p(INDEX_PRINT_CODE);
|
|
|
|
if (cmd.argument().empty())
|
|
|
|
p["type"] = from_ascii("idx");
|
|
|
|
else
|
|
|
|
p["type"] = cmd.argument();
|
2010-10-29 00:25:28 +00:00
|
|
|
string const data = InsetCommand::params2string(p);
|
2009-04-16 07:29:01 +00:00
|
|
|
FuncRequest fr(LFUN_INSET_INSERT, data);
|
|
|
|
dispatch(cur, fr);
|
|
|
|
break;
|
|
|
|
}
|
2014-03-14 13:22:26 +00:00
|
|
|
|
2006-11-04 17:55:36 +00:00
|
|
|
case LFUN_NOMENCL_PRINT:
|
2007-11-23 02:10:00 +00:00
|
|
|
case LFUN_NEWPAGE_INSERT:
|
2003-01-17 09:57:50 +00:00
|
|
|
// do nothing fancy
|
2004-02-13 11:05:29 +00:00
|
|
|
doInsertInset(cur, this, cmd, false, false);
|
2007-11-05 19:41:16 +00:00
|
|
|
cur.posForward();
|
2002-08-28 17:33:42 +00:00
|
|
|
break;
|
|
|
|
|
Fix bugs #8546 and #9055, and introduce new separator inset.
The algorithm used for breaking a paragraph in LaTeX export is changed
for avoiding spurious blank lines causing too much vertical space.
This change is tied to the introduction of a new inset (with two
different specializations) helping in either outputing LaTeX paragraph
breaks or separating environments in LyX. Both of the above goals were
previously achieved by the ---Separator--- layout and can now be
accomplished by the new inset in a more natural way. As an example,
after leaving an environment by hitting the Return key for two times,
a third return automatically inserts a parbreak inset, which is
equivalent to the old separator layout, i.e., it also introduces a
blank line in the output. If this blank line is not wanted, the
parbreak separator can be changed to a plain separator by a right
click of the mouse. Of course, an environment can still be separated
by the following one by using the Alt+P+Return shortcut (or the
corresponding menu key), but now the plain separator inset is used
instead of the old separator layout, such that no blank line occurs in
the LaTeX output.
Old documents are converted such that the LaTeX output remains unchanged.
As a result of this conversion, the old separator layout is replaced by
the new parbreak inset, which may also appear in places where the old
algorithm was introducing blank lines while the new one is not.
Note that not all blank lines were actually affecting the LaTeX output,
because a blank line is simply ignored by the TeX engine when it occurs
in the so called "vertical mode" (e.g., after an alignment environment).
The old ---Separator--- layout is now gone and old layout files using it
are also automatically converted.
Round trip conversions between old and new format should leave a document
unchanged. This means that the new behavior about paragraph breaking is
not "carried back" to the old format. Indeed, this would need introducing
special LaTeX commands in ERT that would accumulate in roundtrip
conversions, horribly cluttering the document. So, when converting a
modified document to old formats, the LaTeX output may slightly differ in
vertical spacing if the document is processed by an old version of LyX.
In other words, forward compatibility is guaranteed, but not backwards.
2014-05-10 21:25:11 +00:00
|
|
|
case LFUN_SEPARATOR_INSERT: {
|
|
|
|
doInsertInset(cur, this, cmd, false, false);
|
|
|
|
cur.posForward();
|
|
|
|
// remove a following space
|
|
|
|
Paragraph & par = cur.paragraph();
|
|
|
|
if (cur.pos() != cur.lastpos() && par.isLineSeparator(cur.pos()))
|
|
|
|
par.eraseChar(cur.pos(), cur.buffer()->params().track_changes);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_DEPTH_DECREMENT:
|
2004-03-18 13:57:20 +00:00
|
|
|
changeDepth(cur, DEC_DEPTH);
|
2003-10-02 14:42:31 +00:00
|
|
|
break;
|
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_DEPTH_INCREMENT:
|
2004-03-18 13:57:20 +00:00
|
|
|
changeDepth(cur, INC_DEPTH);
|
2003-10-02 14:42:31 +00:00
|
|
|
break;
|
|
|
|
|
2008-11-16 00:12:21 +00:00
|
|
|
case LFUN_REGEXP_MODE:
|
|
|
|
regexpDispatch(cur, cmd);
|
|
|
|
break;
|
|
|
|
|
2015-08-01 07:05:33 +00:00
|
|
|
case LFUN_MATH_MODE: {
|
|
|
|
if (cmd.argument() == "on" || cmd.argument() == "") {
|
2004-12-27 18:26:11 +00:00
|
|
|
// don't pass "on" as argument
|
2010-12-04 16:43:41 +00:00
|
|
|
// (it would appear literally in the first cell)
|
2015-08-01 07:05:33 +00:00
|
|
|
docstring sel = cur.selectionAsString(false);
|
2017-07-05 12:31:28 +00:00
|
|
|
InsetMathMacroTemplate * macro = new InsetMathMacroTemplate(cur.buffer());
|
2015-08-01 07:05:33 +00:00
|
|
|
// create a macro template if we see "\\newcommand" somewhere, and
|
|
|
|
// an ordinary formula otherwise
|
|
|
|
if (!sel.empty()
|
|
|
|
&& (sel.find(from_ascii("\\newcommand")) != string::npos
|
|
|
|
|| sel.find(from_ascii("\\newlyxcommand")) != string::npos
|
|
|
|
|| sel.find(from_ascii("\\def")) != string::npos)
|
|
|
|
&& macro->fromString(sel)) {
|
|
|
|
cur.recordUndo();
|
|
|
|
replaceSelection(cur);
|
|
|
|
cur.insert(macro);
|
|
|
|
} else {
|
|
|
|
// no meaningful macro template was found
|
|
|
|
delete macro;
|
|
|
|
mathDispatch(cur,FuncRequest(LFUN_MATH_MODE));
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
// The argument is meaningful
|
|
|
|
// We replace cmd with LFUN_MATH_INSERT because LFUN_MATH_MODE
|
|
|
|
// has a different meaning in math mode
|
|
|
|
mathDispatch(cur, FuncRequest(LFUN_MATH_INSERT,cmd.argument()));
|
2004-02-11 14:45:44 +00:00
|
|
|
break;
|
2015-08-01 07:05:33 +00:00
|
|
|
}
|
2004-02-11 14:45:44 +00:00
|
|
|
|
|
|
|
case LFUN_MATH_MACRO:
|
2006-09-01 15:41:38 +00:00
|
|
|
if (cmd.argument().empty())
|
2006-10-21 00:16:43 +00:00
|
|
|
cur.errorMessage(from_utf8(N_("Missing argument")));
|
2004-02-11 14:45:44 +00:00
|
|
|
else {
|
2011-01-03 20:39:14 +00:00
|
|
|
cur.recordUndo();
|
2006-10-21 00:16:43 +00:00
|
|
|
string s = to_utf8(cmd.argument());
|
2004-02-11 14:45:44 +00:00
|
|
|
string const s1 = token(s, ' ', 1);
|
2005-01-27 21:05:44 +00:00
|
|
|
int const nargs = s1.empty() ? 0 : convert<int>(s1);
|
2004-02-11 14:45:44 +00:00
|
|
|
string const s2 = token(s, ' ', 2);
|
2007-12-21 20:42:46 +00:00
|
|
|
MacroType type = MacroTypeNewcommand;
|
|
|
|
if (s2 == "def")
|
|
|
|
type = MacroTypeDef;
|
2017-07-05 12:31:28 +00:00
|
|
|
InsetMathMacroTemplate * inset = new InsetMathMacroTemplate(cur.buffer(),
|
2009-11-08 11:45:46 +00:00
|
|
|
from_utf8(token(s, ' ', 0)), nargs, false, type);
|
2008-09-06 15:10:23 +00:00
|
|
|
inset->setBuffer(bv->buffer());
|
|
|
|
insertInset(cur, inset);
|
|
|
|
|
|
|
|
// enter macro inset and select the name
|
|
|
|
cur.push(*inset);
|
|
|
|
cur.top().pos() = cur.top().lastpos();
|
|
|
|
cur.resetAnchor();
|
2016-02-28 16:36:29 +00:00
|
|
|
cur.selection(true);
|
2008-09-06 15:10:23 +00:00
|
|
|
cur.top().pos() = 0;
|
2004-02-11 14:45:44 +00:00
|
|
|
}
|
|
|
|
break;
|
2005-01-06 15:40:49 +00:00
|
|
|
|
2015-08-01 07:05:33 +00:00
|
|
|
case LFUN_MATH_DISPLAY:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_MATH_SUBSCRIPT:
|
|
|
|
case LFUN_MATH_SUPERSCRIPT:
|
|
|
|
case LFUN_MATH_INSERT:
|
2009-07-12 21:39:21 +00:00
|
|
|
case LFUN_MATH_AMS_MATRIX:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_MATH_MATRIX:
|
2006-05-07 10:51:19 +00:00
|
|
|
case LFUN_MATH_DELIM:
|
2015-08-01 07:05:33 +00:00
|
|
|
case LFUN_MATH_BIGDELIM:
|
|
|
|
mathDispatch(cur, cmd);
|
2003-11-10 09:06:48 +00:00
|
|
|
break;
|
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_EMPH: {
|
2007-11-14 15:07:08 +00:00
|
|
|
Font font(ignore_font, ignore_language);
|
2007-10-28 18:51:54 +00:00
|
|
|
font.fontInfo().setEmph(FONT_TOGGLE);
|
2004-02-13 07:30:59 +00:00
|
|
|
toggleAndShow(cur, this, font);
|
2003-11-10 09:06:48 +00:00
|
|
|
break;
|
2004-02-06 13:59:26 +00:00
|
|
|
}
|
2003-11-10 09:06:48 +00:00
|
|
|
|
2008-11-26 18:47:52 +00:00
|
|
|
case LFUN_FONT_ITAL: {
|
|
|
|
Font font(ignore_font, ignore_language);
|
|
|
|
font.fontInfo().setShape(ITALIC_SHAPE);
|
|
|
|
toggleAndShow(cur, this, font);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2008-09-15 16:49:11 +00:00
|
|
|
case LFUN_FONT_BOLD:
|
|
|
|
case LFUN_FONT_BOLDSYMBOL: {
|
2007-11-14 15:07:08 +00:00
|
|
|
Font font(ignore_font, ignore_language);
|
2007-10-28 18:51:54 +00:00
|
|
|
font.fontInfo().setSeries(BOLD_SERIES);
|
2004-02-13 07:30:59 +00:00
|
|
|
toggleAndShow(cur, this, font);
|
2003-11-10 09:06:48 +00:00
|
|
|
break;
|
2004-02-06 13:59:26 +00:00
|
|
|
}
|
2003-11-10 09:06:48 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_NOUN: {
|
2007-11-14 15:07:08 +00:00
|
|
|
Font font(ignore_font, ignore_language);
|
2007-10-28 18:51:54 +00:00
|
|
|
font.fontInfo().setNoun(FONT_TOGGLE);
|
2004-02-13 07:30:59 +00:00
|
|
|
toggleAndShow(cur, this, font);
|
2003-11-10 09:06:48 +00:00
|
|
|
break;
|
2004-02-06 13:59:26 +00:00
|
|
|
}
|
2003-11-10 09:06:48 +00:00
|
|
|
|
2007-09-20 18:02:39 +00:00
|
|
|
case LFUN_FONT_TYPEWRITER: {
|
2007-11-14 15:07:08 +00:00
|
|
|
Font font(ignore_font, ignore_language);
|
2007-10-28 18:51:54 +00:00
|
|
|
font.fontInfo().setFamily(TYPEWRITER_FAMILY); // no good
|
2004-02-13 07:30:59 +00:00
|
|
|
toggleAndShow(cur, this, font);
|
2003-11-10 09:06:48 +00:00
|
|
|
break;
|
2004-02-06 13:59:26 +00:00
|
|
|
}
|
2003-11-10 09:06:48 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_SANS: {
|
2007-11-14 15:07:08 +00:00
|
|
|
Font font(ignore_font, ignore_language);
|
2007-10-28 18:51:54 +00:00
|
|
|
font.fontInfo().setFamily(SANS_FAMILY);
|
2004-02-13 07:30:59 +00:00
|
|
|
toggleAndShow(cur, this, font);
|
2003-11-10 09:06:48 +00:00
|
|
|
break;
|
2004-02-06 13:59:26 +00:00
|
|
|
}
|
2003-11-10 09:06:48 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_ROMAN: {
|
2007-11-14 15:07:08 +00:00
|
|
|
Font font(ignore_font, ignore_language);
|
2007-10-28 18:51:54 +00:00
|
|
|
font.fontInfo().setFamily(ROMAN_FAMILY);
|
2004-02-13 07:30:59 +00:00
|
|
|
toggleAndShow(cur, this, font);
|
2003-11-10 09:06:48 +00:00
|
|
|
break;
|
2004-02-06 13:59:26 +00:00
|
|
|
}
|
2003-11-10 09:06:48 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_DEFAULT: {
|
2007-10-28 18:51:54 +00:00
|
|
|
Font font(inherit_font, ignore_language);
|
2004-02-13 07:30:59 +00:00
|
|
|
toggleAndShow(cur, this, font);
|
2003-11-10 09:06:48 +00:00
|
|
|
break;
|
2004-02-06 13:59:26 +00:00
|
|
|
}
|
2003-11-10 09:06:48 +00:00
|
|
|
|
2009-05-03 22:45:14 +00:00
|
|
|
case LFUN_FONT_STRIKEOUT: {
|
|
|
|
Font font(ignore_font, ignore_language);
|
|
|
|
font.fontInfo().setStrikeout(FONT_TOGGLE);
|
|
|
|
toggleAndShow(cur, this, font);
|
|
|
|
break;
|
|
|
|
}
|
2009-05-05 09:26:28 +00:00
|
|
|
|
2017-04-04 22:01:19 +00:00
|
|
|
case LFUN_FONT_CROSSOUT: {
|
|
|
|
Font font(ignore_font, ignore_language);
|
|
|
|
font.fontInfo().setXout(FONT_TOGGLE);
|
|
|
|
toggleAndShow(cur, this, font);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2014-02-11 10:00:20 +00:00
|
|
|
case LFUN_FONT_UNDERUNDERLINE: {
|
2009-05-05 09:26:28 +00:00
|
|
|
Font font(ignore_font, ignore_language);
|
|
|
|
font.fontInfo().setUuline(FONT_TOGGLE);
|
|
|
|
toggleAndShow(cur, this, font);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2014-02-11 10:00:20 +00:00
|
|
|
case LFUN_FONT_UNDERWAVE: {
|
2009-05-05 09:26:28 +00:00
|
|
|
Font font(ignore_font, ignore_language);
|
|
|
|
font.fontInfo().setUwave(FONT_TOGGLE);
|
|
|
|
toggleAndShow(cur, this, font);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_UNDERLINE: {
|
2007-11-14 15:07:08 +00:00
|
|
|
Font font(ignore_font, ignore_language);
|
2007-10-28 18:51:54 +00:00
|
|
|
font.fontInfo().setUnderbar(FONT_TOGGLE);
|
2004-02-13 07:30:59 +00:00
|
|
|
toggleAndShow(cur, this, font);
|
2003-11-10 09:06:48 +00:00
|
|
|
break;
|
2004-02-06 13:59:26 +00:00
|
|
|
}
|
2003-11-10 09:06:48 +00:00
|
|
|
|
2004-02-06 13:59:26 +00:00
|
|
|
case LFUN_FONT_SIZE: {
|
2007-11-14 15:07:08 +00:00
|
|
|
Font font(ignore_font, ignore_language);
|
2007-10-28 18:51:54 +00:00
|
|
|
setLyXSize(to_utf8(cmd.argument()), font.fontInfo());
|
2004-02-13 07:30:59 +00:00
|
|
|
toggleAndShow(cur, this, font);
|
2003-11-10 09:06:48 +00:00
|
|
|
break;
|
2004-02-06 13:59:26 +00:00
|
|
|
}
|
2003-11-10 09:06:48 +00:00
|
|
|
|
2004-02-06 13:59:26 +00:00
|
|
|
case LFUN_LANGUAGE: {
|
2012-10-03 05:27:36 +00:00
|
|
|
string const lang_arg = cmd.getArg(0);
|
|
|
|
bool const reset = (lang_arg.empty() || lang_arg == "reset");
|
|
|
|
Language const * lang =
|
|
|
|
reset ? reset_language
|
|
|
|
: languages.getLanguage(lang_arg);
|
|
|
|
// we allow reset_language, which is 0, but only if it
|
|
|
|
// was requested via empty or "reset" arg.
|
|
|
|
if (!lang && !reset)
|
2004-02-06 13:59:26 +00:00
|
|
|
break;
|
2012-10-03 05:27:36 +00:00
|
|
|
bool const toggle = (cmd.getArg(1) != "set");
|
2011-03-09 14:15:34 +00:00
|
|
|
selectWordWhenUnderCursor(cur, WHOLE_WORD_STRICT);
|
2007-11-14 15:07:08 +00:00
|
|
|
Font font(ignore_font, lang);
|
2012-10-03 05:27:36 +00:00
|
|
|
toggleAndShow(cur, this, font, toggle);
|
2003-11-10 09:06:48 +00:00
|
|
|
break;
|
2004-02-06 13:59:26 +00:00
|
|
|
}
|
2003-11-10 09:06:48 +00:00
|
|
|
|
2008-06-11 08:35:15 +00:00
|
|
|
case LFUN_TEXTSTYLE_APPLY:
|
2004-02-13 07:30:59 +00:00
|
|
|
toggleAndShow(cur, this, freefont, toggleall);
|
2006-09-11 08:54:10 +00:00
|
|
|
cur.message(_("Character set"));
|
2003-11-10 09:06:48 +00:00
|
|
|
break;
|
|
|
|
|
2004-02-06 13:59:26 +00:00
|
|
|
// Set the freefont using the contents of \param data dispatched from
|
|
|
|
// the frontends and apply it at the current cursor location.
|
2008-06-11 08:35:15 +00:00
|
|
|
case LFUN_TEXTSTYLE_UPDATE: {
|
2007-04-29 18:17:15 +00:00
|
|
|
Font font;
|
2004-02-06 13:59:26 +00:00
|
|
|
bool toggle;
|
2007-09-29 11:00:18 +00:00
|
|
|
if (font.fromString(to_utf8(cmd.argument()), toggle)) {
|
2004-02-06 13:59:26 +00:00
|
|
|
freefont = font;
|
|
|
|
toggleall = toggle;
|
2004-02-13 07:30:59 +00:00
|
|
|
toggleAndShow(cur, this, freefont, toggleall);
|
2006-09-11 08:54:10 +00:00
|
|
|
cur.message(_("Character set"));
|
2007-10-29 22:03:59 +00:00
|
|
|
} else {
|
|
|
|
lyxerr << "Argument not ok";
|
2004-02-06 13:59:26 +00:00
|
|
|
}
|
2003-11-10 09:06:48 +00:00
|
|
|
break;
|
2004-02-06 13:59:26 +00:00
|
|
|
}
|
2003-11-22 14:44:59 +00:00
|
|
|
|
2003-11-10 09:06:48 +00:00
|
|
|
case LFUN_FINISHED_LEFT:
|
2007-11-15 20:04:51 +00:00
|
|
|
LYXERR(Debug::DEBUG, "handle LFUN_FINISHED_LEFT:\n" << cur);
|
2008-10-13 11:25:37 +00:00
|
|
|
// We're leaving an inset, going left. If the inset is LTR, we're
|
2008-02-10 19:52:45 +00:00
|
|
|
// leaving from the front, so we should not move (remain at --- but
|
2008-10-13 11:25:37 +00:00
|
|
|
// not in --- the inset). If the inset is RTL, move left, without
|
2008-02-10 19:52:45 +00:00
|
|
|
// entering the inset itself; i.e., move to after the inset.
|
|
|
|
if (cur.paragraph().getFontSettings(
|
|
|
|
cur.bv().buffer().params(), cur.pos()).isRightToLeft())
|
|
|
|
cursorVisLeft(cur, true);
|
2003-11-10 09:06:48 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case LFUN_FINISHED_RIGHT:
|
2007-11-15 20:04:51 +00:00
|
|
|
LYXERR(Debug::DEBUG, "handle LFUN_FINISHED_RIGHT:\n" << cur);
|
2008-10-13 11:25:37 +00:00
|
|
|
// We're leaving an inset, going right. If the inset is RTL, we're
|
2008-02-10 19:52:45 +00:00
|
|
|
// leaving from the front, so we should not move (remain at --- but
|
2008-10-13 11:25:37 +00:00
|
|
|
// not in --- the inset). If the inset is LTR, move right, without
|
2008-02-10 19:52:45 +00:00
|
|
|
// entering the inset itself; i.e., move to after the inset.
|
|
|
|
if (!cur.paragraph().getFontSettings(
|
|
|
|
cur.bv().buffer().params(), cur.pos()).isRightToLeft())
|
|
|
|
cursorVisRight(cur, true);
|
2003-11-10 09:06:48 +00:00
|
|
|
break;
|
|
|
|
|
2007-10-22 22:18:52 +00:00
|
|
|
case LFUN_FINISHED_BACKWARD:
|
2007-11-15 20:04:51 +00:00
|
|
|
LYXERR(Debug::DEBUG, "handle LFUN_FINISHED_BACKWARD:\n" << cur);
|
2015-07-21 09:50:36 +00:00
|
|
|
cur.setCurrentFont();
|
2007-10-22 22:18:52 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case LFUN_FINISHED_FORWARD:
|
2007-11-15 20:04:51 +00:00
|
|
|
LYXERR(Debug::DEBUG, "handle LFUN_FINISHED_FORWARD:\n" << cur);
|
2007-10-22 22:18:52 +00:00
|
|
|
++cur.pos();
|
|
|
|
cur.setCurrentFont();
|
|
|
|
break;
|
|
|
|
|
2004-02-06 13:59:26 +00:00
|
|
|
case LFUN_LAYOUT_PARAGRAPH: {
|
|
|
|
string data;
|
|
|
|
params2string(cur.paragraph(), data);
|
|
|
|
data = "show\n" + data;
|
2007-11-18 00:39:15 +00:00
|
|
|
bv->showDialog("paragraph", data);
|
2004-02-06 13:59:26 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case LFUN_PARAGRAPH_UPDATE: {
|
|
|
|
string data;
|
|
|
|
params2string(cur.paragraph(), data);
|
|
|
|
|
|
|
|
// Will the paragraph accept changes from the dialog?
|
2008-10-13 11:25:37 +00:00
|
|
|
bool const accept =
|
Fix bug 4037 and related problems. The patch has been cleaned up a bit
from the one posted to the list.
The basic idea has two parts. First, we hard code an "empty layout"
(called PlainLayout, for want of a better name) in TextClass and read it
before doing anything else. It can therefore be customized by classes,
if they want---say, to make it left-aligned. Second, InsetText's are
divided into three types: (i) normal ones, that use the "default" layout
defined by the text class; (ii) highly restrictive ones, such as ERT and
(not quite an inset) table cells, which demand the empty layout; (iii)
middling ones, which default to an empty layout and use the empty layout
in place of the default. (This is so we don't get the same problem we
had with ERT in e.g. footnotes.) The type of inset is signaled by new
methods InsetText::forceEmptyLayout() and InsetText::useEmptyLayout().
(The latter might better be called: useEmptyLayoutInsteadOfDefault(),
but that's silly.) The old InsetText::forceDefaultParagraphs() has been
split into these, plus a new method InsetText::allowParagraphCustomization().
A lot of the changes just adapt to this change.
The other big change is in GuiToolbar: We want to show LyXDefault and
the "default" layout only when they're active.
There are a handful of places where I'm not entirely sure whether we
should be using forceEmptyLayout or !allowParagraphCustomization() or
both. The InsetCaption is one of these. These places, and some others,
are marked with FIXMEs, so I'd appreciate it if people would search
through the patch and let me know whether these need changing. If they
don't, the FIXMEs can be deleted.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@22966 a592a061-630c-0410-9148-cb99ea01b6c8
2008-02-12 17:31:07 +00:00
|
|
|
cur.inset().allowParagraphCustomization(cur.idx());
|
2004-02-06 13:59:26 +00:00
|
|
|
|
2005-01-06 15:40:49 +00:00
|
|
|
data = "update " + convert<string>(accept) + '\n' + data;
|
2006-09-19 13:36:20 +00:00
|
|
|
bv->updateDialog("paragraph", data);
|
2004-02-06 13:59:26 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_ACCENT_UMLAUT:
|
|
|
|
case LFUN_ACCENT_CIRCUMFLEX:
|
|
|
|
case LFUN_ACCENT_GRAVE:
|
|
|
|
case LFUN_ACCENT_ACUTE:
|
|
|
|
case LFUN_ACCENT_TILDE:
|
2015-08-13 09:15:19 +00:00
|
|
|
case LFUN_ACCENT_PERISPOMENI:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_ACCENT_CEDILLA:
|
|
|
|
case LFUN_ACCENT_MACRON:
|
|
|
|
case LFUN_ACCENT_DOT:
|
|
|
|
case LFUN_ACCENT_UNDERDOT:
|
|
|
|
case LFUN_ACCENT_UNDERBAR:
|
|
|
|
case LFUN_ACCENT_CARON:
|
|
|
|
case LFUN_ACCENT_BREVE:
|
|
|
|
case LFUN_ACCENT_TIE:
|
|
|
|
case LFUN_ACCENT_HUNGARIAN_UMLAUT:
|
|
|
|
case LFUN_ACCENT_CIRCLE:
|
|
|
|
case LFUN_ACCENT_OGONEK:
|
2010-04-09 19:00:42 +00:00
|
|
|
theApp()->handleKeyFunc(cmd.action());
|
2006-09-01 15:41:38 +00:00
|
|
|
if (!cmd.argument().empty())
|
|
|
|
// FIXME: Are all these characters encoded in one byte in utf8?
|
2007-06-11 22:05:44 +00:00
|
|
|
bv->translateAndInsert(cmd.argument()[0], this, cur);
|
2010-10-14 14:47:33 +00:00
|
|
|
cur.screenUpdateFlags(Update::FitCursor);
|
2004-02-06 13:59:26 +00:00
|
|
|
break;
|
|
|
|
|
2008-06-02 11:31:03 +00:00
|
|
|
case LFUN_FLOAT_LIST_INSERT: {
|
2008-02-28 01:42:02 +00:00
|
|
|
DocumentClass const & tclass = bv->buffer().params().documentClass();
|
2006-10-21 00:16:43 +00:00
|
|
|
if (tclass.floats().typeExist(to_utf8(cmd.argument()))) {
|
2007-10-18 11:51:17 +00:00
|
|
|
cur.recordUndo();
|
2007-07-30 10:33:43 +00:00
|
|
|
if (cur.selection())
|
|
|
|
cutSelection(cur, true, false);
|
2004-02-12 16:36:01 +00:00
|
|
|
breakParagraph(cur);
|
|
|
|
|
|
|
|
if (cur.lastpos() != 0) {
|
2007-10-22 22:18:52 +00:00
|
|
|
cursorBackward(cur);
|
2004-02-12 16:36:01 +00:00
|
|
|
breakParagraph(cur);
|
|
|
|
}
|
|
|
|
|
2008-07-10 17:41:52 +00:00
|
|
|
docstring const laystr = cur.inset().usePlainLayout() ?
|
2008-08-01 20:57:27 +00:00
|
|
|
tclass.plainLayoutName() :
|
2008-03-26 17:11:49 +00:00
|
|
|
tclass.defaultLayoutName();
|
|
|
|
setLayout(cur, laystr);
|
Add LFUN_PARAGRAPH_PARAMS (= paragraph-params), used for changing a paragraph's alignment, spacing, etc. This is complementary to LFUN_PARAGRAPH_PARAMS_APPLY, which sets the parameters. The difference is that APPLY over-rides all existing parameters, setting any not given to the default, whereas this one simply changes those that are given. So
paragraph-params \align right
will align the paragraph right, leaving spacing, etc, as they were, whereas
paragraph-params-apply \align right
will align the paragraph right but also reset all other parameters to defaults. Note, by the way, that this means that
paragraph-params-apply
sets everything to default.
Some new arguments have also been introduced. These are:
\indent
\indent-toggle
\spacing default
Of course, none of these are found in valid LyX files, but they are useful in menu bindings, etc.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19581 a592a061-630c-0410-9148-cb99ea01b6c8
2007-08-15 02:21:09 +00:00
|
|
|
ParagraphParameters p;
|
2008-08-14 15:53:32 +00:00
|
|
|
// FIXME If this call were replaced with one to clearParagraphParams(),
|
|
|
|
// then we could get rid of this method altogether.
|
Add LFUN_PARAGRAPH_PARAMS (= paragraph-params), used for changing a paragraph's alignment, spacing, etc. This is complementary to LFUN_PARAGRAPH_PARAMS_APPLY, which sets the parameters. The difference is that APPLY over-rides all existing parameters, setting any not given to the default, whereas this one simply changes those that are given. So
paragraph-params \align right
will align the paragraph right, leaving spacing, etc, as they were, whereas
paragraph-params-apply \align right
will align the paragraph right but also reset all other parameters to defaults. Note, by the way, that this means that
paragraph-params-apply
sets everything to default.
Some new arguments have also been introduced. These are:
\indent
\indent-toggle
\spacing default
Of course, none of these are found in valid LyX files, but they are useful in menu bindings, etc.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19581 a592a061-630c-0410-9148-cb99ea01b6c8
2007-08-15 02:21:09 +00:00
|
|
|
setParagraphs(cur, p);
|
2008-10-13 11:25:37 +00:00
|
|
|
// FIXME This should be simplified when InsetFloatList takes a
|
2008-03-26 17:02:24 +00:00
|
|
|
// Buffer in its constructor.
|
2009-11-08 16:10:34 +00:00
|
|
|
InsetFloatList * ifl = new InsetFloatList(cur.buffer(), to_utf8(cmd.argument()));
|
2008-03-26 17:02:24 +00:00
|
|
|
ifl->setBuffer(bv->buffer());
|
|
|
|
insertInset(cur, ifl);
|
2007-11-05 19:41:16 +00:00
|
|
|
cur.posForward();
|
2004-02-12 16:36:01 +00:00
|
|
|
} else {
|
|
|
|
lyxerr << "Non-existent float type: "
|
2006-10-21 00:16:43 +00:00
|
|
|
<< to_utf8(cmd.argument()) << endl;
|
2004-02-12 16:36:01 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-05-08 18:09:19 +00:00
|
|
|
case LFUN_CHANGE_ACCEPT: {
|
2007-01-25 22:28:15 +00:00
|
|
|
acceptOrRejectChanges(cur, ACCEPT);
|
2004-02-13 07:30:59 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-05-08 18:09:19 +00:00
|
|
|
case LFUN_CHANGE_REJECT: {
|
2007-01-25 22:28:15 +00:00
|
|
|
acceptOrRejectChanges(cur, REJECT);
|
2004-02-13 07:30:59 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case LFUN_THESAURUS_ENTRY: {
|
2015-07-16 20:06:23 +00:00
|
|
|
Language const * language = cur.getFont().language();
|
2006-09-03 07:02:38 +00:00
|
|
|
docstring arg = cmd.argument();
|
2004-02-13 07:30:59 +00:00
|
|
|
if (arg.empty()) {
|
|
|
|
arg = cur.selectionAsString(false);
|
|
|
|
// FIXME
|
|
|
|
if (arg.size() > 100 || arg.empty()) {
|
|
|
|
// Get word or selection
|
2006-10-21 00:16:43 +00:00
|
|
|
selectWordWhenUnderCursor(cur, WHOLE_WORD);
|
2004-02-13 07:30:59 +00:00
|
|
|
arg = cur.selectionAsString(false);
|
2015-07-16 20:06:23 +00:00
|
|
|
arg += " lang=" + from_ascii(language->lang());
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
string lang = cmd.getArg(1);
|
|
|
|
// This duplicates the code in GuiThesaurus::initialiseParams
|
|
|
|
if (prefixIs(lang, "lang=")) {
|
|
|
|
language = languages.getLanguage(lang.substr(5));
|
|
|
|
if (!language)
|
|
|
|
language = cur.getFont().language();
|
2004-02-13 07:30:59 +00:00
|
|
|
}
|
|
|
|
}
|
2015-07-16 20:06:23 +00:00
|
|
|
string lang = language->code();
|
|
|
|
if (lyxrc.thesaurusdir_path.empty() && !thesaurus.thesaurusInstalled(from_ascii(lang))) {
|
|
|
|
LYXERR(Debug::ACTION, "Command " << cmd << ". Thesaurus not found for language " << lang);
|
2015-04-12 13:55:01 +00:00
|
|
|
frontend::Alert::warning(_("Path to thesaurus directory not set!"),
|
|
|
|
_("The path to the thesaurus directory has not been specified.\n"
|
|
|
|
"The thesaurus is not functional.\n"
|
|
|
|
"Please refer to sec. 6.15.1 of the User's Guide for setup\n"
|
|
|
|
"instructions."));
|
|
|
|
}
|
2007-11-18 00:39:15 +00:00
|
|
|
bv->showDialog("thesaurus", to_utf8(arg));
|
2004-02-13 07:30:59 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-01-19 08:21:56 +00:00
|
|
|
case LFUN_SPELLING_ADD: {
|
2015-07-16 19:26:41 +00:00
|
|
|
Language const * language = getLanguage(cur, cmd.getArg(1));
|
2010-01-19 08:21:56 +00:00
|
|
|
docstring word = from_utf8(cmd.getArg(0));
|
|
|
|
if (word.empty()) {
|
|
|
|
word = cur.selectionAsString(false);
|
|
|
|
// FIXME
|
|
|
|
if (word.size() > 100 || word.empty()) {
|
|
|
|
// Get word or selection
|
|
|
|
selectWordWhenUnderCursor(cur, WHOLE_WORD);
|
|
|
|
word = cur.selectionAsString(false);
|
|
|
|
}
|
2015-03-27 07:07:05 +00:00
|
|
|
}
|
2015-07-16 19:26:41 +00:00
|
|
|
WordLangTuple wl(word, language);
|
2010-01-19 08:21:56 +00:00
|
|
|
theSpellChecker()->insert(wl);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case LFUN_SPELLING_IGNORE: {
|
2015-07-16 19:26:41 +00:00
|
|
|
Language const * language = getLanguage(cur, cmd.getArg(1));
|
2010-01-19 08:21:56 +00:00
|
|
|
docstring word = from_utf8(cmd.getArg(0));
|
|
|
|
if (word.empty()) {
|
|
|
|
word = cur.selectionAsString(false);
|
|
|
|
// FIXME
|
|
|
|
if (word.size() > 100 || word.empty()) {
|
|
|
|
// Get word or selection
|
|
|
|
selectWordWhenUnderCursor(cur, WHOLE_WORD);
|
|
|
|
word = cur.selectionAsString(false);
|
|
|
|
}
|
2015-03-27 07:07:05 +00:00
|
|
|
}
|
2015-07-16 19:26:41 +00:00
|
|
|
WordLangTuple wl(word, language);
|
2010-01-19 08:21:56 +00:00
|
|
|
theSpellChecker()->accept(wl);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-08-05 20:10:40 +00:00
|
|
|
case LFUN_SPELLING_REMOVE: {
|
2015-07-16 19:26:41 +00:00
|
|
|
Language const * language = getLanguage(cur, cmd.getArg(1));
|
2010-08-05 20:10:40 +00:00
|
|
|
docstring word = from_utf8(cmd.getArg(0));
|
|
|
|
if (word.empty()) {
|
|
|
|
word = cur.selectionAsString(false);
|
|
|
|
// FIXME
|
|
|
|
if (word.size() > 100 || word.empty()) {
|
|
|
|
// Get word or selection
|
|
|
|
selectWordWhenUnderCursor(cur, WHOLE_WORD);
|
|
|
|
word = cur.selectionAsString(false);
|
|
|
|
}
|
2015-03-27 07:07:05 +00:00
|
|
|
}
|
2015-07-16 19:26:41 +00:00
|
|
|
WordLangTuple wl(word, language);
|
2010-08-05 20:10:40 +00:00
|
|
|
theSpellChecker()->remove(wl);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_PARAGRAPH_PARAMS_APPLY: {
|
2004-02-13 11:05:29 +00:00
|
|
|
// Given data, an encoding of the ParagraphParameters
|
|
|
|
// generated in the Paragraph dialog, this function sets
|
Add LFUN_PARAGRAPH_PARAMS (= paragraph-params), used for changing a paragraph's alignment, spacing, etc. This is complementary to LFUN_PARAGRAPH_PARAMS_APPLY, which sets the parameters. The difference is that APPLY over-rides all existing parameters, setting any not given to the default, whereas this one simply changes those that are given. So
paragraph-params \align right
will align the paragraph right, leaving spacing, etc, as they were, whereas
paragraph-params-apply \align right
will align the paragraph right but also reset all other parameters to defaults. Note, by the way, that this means that
paragraph-params-apply
sets everything to default.
Some new arguments have also been introduced. These are:
\indent
\indent-toggle
\spacing default
Of course, none of these are found in valid LyX files, but they are useful in menu bindings, etc.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19581 a592a061-630c-0410-9148-cb99ea01b6c8
2007-08-15 02:21:09 +00:00
|
|
|
// the current paragraph, or currently selected paragraphs,
|
2008-10-13 11:25:37 +00:00
|
|
|
// appropriately.
|
Add LFUN_PARAGRAPH_PARAMS (= paragraph-params), used for changing a paragraph's alignment, spacing, etc. This is complementary to LFUN_PARAGRAPH_PARAMS_APPLY, which sets the parameters. The difference is that APPLY over-rides all existing parameters, setting any not given to the default, whereas this one simply changes those that are given. So
paragraph-params \align right
will align the paragraph right, leaving spacing, etc, as they were, whereas
paragraph-params-apply \align right
will align the paragraph right but also reset all other parameters to defaults. Note, by the way, that this means that
paragraph-params-apply
sets everything to default.
Some new arguments have also been introduced. These are:
\indent
\indent-toggle
\spacing default
Of course, none of these are found in valid LyX files, but they are useful in menu bindings, etc.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19581 a592a061-630c-0410-9148-cb99ea01b6c8
2007-08-15 02:21:09 +00:00
|
|
|
// NOTE: This function overrides all existing settings.
|
|
|
|
setParagraphs(cur, cmd.argument());
|
|
|
|
cur.message(_("Paragraph layout set"));
|
|
|
|
break;
|
|
|
|
}
|
2008-10-13 11:25:37 +00:00
|
|
|
|
Add LFUN_PARAGRAPH_PARAMS (= paragraph-params), used for changing a paragraph's alignment, spacing, etc. This is complementary to LFUN_PARAGRAPH_PARAMS_APPLY, which sets the parameters. The difference is that APPLY over-rides all existing parameters, setting any not given to the default, whereas this one simply changes those that are given. So
paragraph-params \align right
will align the paragraph right, leaving spacing, etc, as they were, whereas
paragraph-params-apply \align right
will align the paragraph right but also reset all other parameters to defaults. Note, by the way, that this means that
paragraph-params-apply
sets everything to default.
Some new arguments have also been introduced. These are:
\indent
\indent-toggle
\spacing default
Of course, none of these are found in valid LyX files, but they are useful in menu bindings, etc.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19581 a592a061-630c-0410-9148-cb99ea01b6c8
2007-08-15 02:21:09 +00:00
|
|
|
case LFUN_PARAGRAPH_PARAMS: {
|
|
|
|
// Given data, an encoding of the ParagraphParameters as we'd
|
2008-10-13 11:25:37 +00:00
|
|
|
// find them in a LyX file, this function modifies the current paragraph,
|
|
|
|
// or currently selected paragraphs.
|
Add LFUN_PARAGRAPH_PARAMS (= paragraph-params), used for changing a paragraph's alignment, spacing, etc. This is complementary to LFUN_PARAGRAPH_PARAMS_APPLY, which sets the parameters. The difference is that APPLY over-rides all existing parameters, setting any not given to the default, whereas this one simply changes those that are given. So
paragraph-params \align right
will align the paragraph right, leaving spacing, etc, as they were, whereas
paragraph-params-apply \align right
will align the paragraph right but also reset all other parameters to defaults. Note, by the way, that this means that
paragraph-params-apply
sets everything to default.
Some new arguments have also been introduced. These are:
\indent
\indent-toggle
\spacing default
Of course, none of these are found in valid LyX files, but they are useful in menu bindings, etc.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19581 a592a061-630c-0410-9148-cb99ea01b6c8
2007-08-15 02:21:09 +00:00
|
|
|
// NOTE: This function only modifies, and does not override, existing
|
|
|
|
// settings.
|
|
|
|
setParagraphs(cur, cmd.argument(), true);
|
2006-09-11 08:54:10 +00:00
|
|
|
cur.message(_("Paragraph layout set"));
|
2004-02-13 11:05:29 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2004-02-20 17:19:53 +00:00
|
|
|
case LFUN_ESCAPE:
|
2004-03-25 09:16:36 +00:00
|
|
|
if (cur.selection()) {
|
2016-02-28 16:36:29 +00:00
|
|
|
cur.selection(false);
|
2004-03-25 09:16:36 +00:00
|
|
|
} else {
|
|
|
|
cur.undispatched();
|
2007-10-22 22:18:52 +00:00
|
|
|
// This used to be LFUN_FINISHED_RIGHT, I think FORWARD is more
|
|
|
|
// correct, but I'm not 100% sure -- dov, 071019
|
|
|
|
cmd = FuncRequest(LFUN_FINISHED_FORWARD);
|
2004-03-25 09:16:36 +00:00
|
|
|
}
|
2004-02-20 17:19:53 +00:00
|
|
|
break;
|
|
|
|
|
2007-11-06 17:13:43 +00:00
|
|
|
case LFUN_OUTLINE_UP:
|
2018-01-27 08:59:19 +00:00
|
|
|
outline(OutlineUp, cur, this);
|
2007-11-06 17:13:43 +00:00
|
|
|
setCursor(cur, cur.pit(), 0);
|
2010-07-09 14:37:00 +00:00
|
|
|
cur.forceBufferUpdate();
|
2007-11-06 17:13:43 +00:00
|
|
|
needsUpdate = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LFUN_OUTLINE_DOWN:
|
2018-01-27 08:59:19 +00:00
|
|
|
outline(OutlineDown, cur, this);
|
2007-11-06 17:13:43 +00:00
|
|
|
setCursor(cur, cur.pit(), 0);
|
2010-07-09 14:37:00 +00:00
|
|
|
cur.forceBufferUpdate();
|
2007-11-06 17:13:43 +00:00
|
|
|
needsUpdate = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LFUN_OUTLINE_IN:
|
2018-01-27 08:59:19 +00:00
|
|
|
outline(OutlineIn, cur, this);
|
2010-07-09 14:37:00 +00:00
|
|
|
cur.forceBufferUpdate();
|
2007-11-06 17:13:43 +00:00
|
|
|
needsUpdate = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LFUN_OUTLINE_OUT:
|
2018-01-27 08:59:19 +00:00
|
|
|
outline(OutlineOut, cur, this);
|
2010-07-09 14:37:00 +00:00
|
|
|
cur.forceBufferUpdate();
|
2007-11-06 17:13:43 +00:00
|
|
|
needsUpdate = true;
|
|
|
|
break;
|
|
|
|
|
2014-10-14 19:55:04 +00:00
|
|
|
case LFUN_SERVER_GET_STATISTICS:
|
|
|
|
{
|
|
|
|
DocIterator from, to;
|
|
|
|
if (cur.selection()) {
|
|
|
|
from = cur.selectionBegin();
|
|
|
|
to = cur.selectionEnd();
|
|
|
|
} else {
|
|
|
|
from = doc_iterator_begin(cur.buffer());
|
|
|
|
to = doc_iterator_end(cur.buffer());
|
|
|
|
}
|
|
|
|
|
|
|
|
cur.buffer()->updateStatistics(from, to);
|
|
|
|
string const arg0 = cmd.getArg(0);
|
|
|
|
if (arg0 == "words") {
|
|
|
|
cur.message(convert<docstring>(cur.buffer()->wordCount()));
|
|
|
|
} else if (arg0 == "chars") {
|
|
|
|
cur.message(convert<docstring>(cur.buffer()->charCount(false)));
|
|
|
|
} else if (arg0 == "chars-space") {
|
|
|
|
cur.message(convert<docstring>(cur.buffer()->charCount(true)));
|
|
|
|
} else {
|
|
|
|
cur.message(convert<docstring>(cur.buffer()->wordCount()) + " "
|
|
|
|
+ convert<docstring>(cur.buffer()->charCount(false)) + " "
|
|
|
|
+ convert<docstring>(cur.buffer()->charCount(true)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2002-08-20 13:00:25 +00:00
|
|
|
default:
|
2007-11-29 21:10:35 +00:00
|
|
|
LYXERR(Debug::ACTION, "Command " << cmd << " not DISPATCHED by Text");
|
2004-03-01 17:12:09 +00:00
|
|
|
cur.undispatched();
|
2004-02-20 17:19:53 +00:00
|
|
|
break;
|
2002-08-20 13:00:25 +00:00
|
|
|
}
|
2004-05-18 07:18:02 +00:00
|
|
|
|
2006-10-22 11:46:36 +00:00
|
|
|
needsUpdate |= (cur.pos() != cur.lastpos()) && cur.selection();
|
2006-11-17 17:42:52 +00:00
|
|
|
|
2010-12-28 13:20:20 +00:00
|
|
|
if (lyxrc.spellcheck_continuously && !needsUpdate) {
|
2010-12-22 07:29:16 +00:00
|
|
|
// Check for misspelled text
|
|
|
|
// The redraw is useful because of the painting of
|
|
|
|
// misspelled markers depends on the cursor position.
|
|
|
|
// Trigger a redraw for cursor moves inside misspelled text.
|
2010-12-28 13:20:20 +00:00
|
|
|
if (!cur.inTexted()) {
|
|
|
|
// move from regular text to math
|
|
|
|
needsUpdate = last_misspelled;
|
2011-01-29 12:28:02 +00:00
|
|
|
} else if (oldTopSlice != cur.top() || oldBoundary != cur.boundary()) {
|
2010-12-28 13:20:20 +00:00
|
|
|
// move inside regular text
|
2011-01-29 12:28:02 +00:00
|
|
|
needsUpdate = last_misspelled
|
|
|
|
|| cur.paragraph().isMisspelled(cur.pos(), true);
|
2010-12-22 07:29:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-11-17 17:42:52 +00:00
|
|
|
// FIXME: The cursor flag is reset two lines below
|
|
|
|
// so we need to check here if some of the LFUN did touch that.
|
2007-04-29 23:33:02 +00:00
|
|
|
// for now only Text::erase() and Text::backspace() do that.
|
2006-11-17 17:42:52 +00:00
|
|
|
// The plan is to verify all the LFUNs and then to remove this
|
|
|
|
// singleParUpdate boolean altogether.
|
2010-10-13 17:28:55 +00:00
|
|
|
if (cur.result().screenUpdate() & Update::Force) {
|
2006-11-17 17:42:52 +00:00
|
|
|
singleParUpdate = false;
|
|
|
|
needsUpdate = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: the following code should go in favor of fine grained
|
|
|
|
// update flag treatment.
|
2006-12-29 23:54:48 +00:00
|
|
|
if (singleParUpdate) {
|
2008-02-22 11:07:41 +00:00
|
|
|
// Inserting characters does not change par height in general. So, try
|
|
|
|
// to update _only_ this paragraph. BufferView will detect if a full
|
|
|
|
// metrics update is needed anyway.
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.screenUpdateFlags(Update::SinglePar | Update::FitCursor);
|
2008-02-22 11:07:41 +00:00
|
|
|
return;
|
2006-12-29 23:54:48 +00:00
|
|
|
}
|
2005-02-08 02:06:39 +00:00
|
|
|
if (!needsUpdate
|
|
|
|
&& &oldTopSlice.inset() == &cur.inset()
|
|
|
|
&& oldTopSlice.idx() == cur.idx()
|
2011-01-29 12:28:02 +00:00
|
|
|
&& !oldSelection // oldSelection is a backup of cur.selection() at the beginning of the function.
|
2005-02-08 02:06:39 +00:00
|
|
|
&& !cur.selection())
|
2006-11-27 12:49:28 +00:00
|
|
|
// FIXME: it would be better if we could just do this
|
|
|
|
//
|
|
|
|
//if (cur.result().update() != Update::FitCursor)
|
2010-07-08 20:04:35 +00:00
|
|
|
// cur.noScreenUpdate();
|
2007-05-28 22:27:45 +00:00
|
|
|
//
|
2006-11-27 12:49:28 +00:00
|
|
|
// But some LFUNs do not set Update::FitCursor when needed, so we
|
|
|
|
// do it for all. This is not very harmfull as FitCursor will provoke
|
|
|
|
// a full redraw only if needed but still, a proper review of all LFUN
|
|
|
|
// should be done and this needsUpdate boolean can then be removed.
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.screenUpdateFlags(Update::FitCursor);
|
2005-02-08 02:06:39 +00:00
|
|
|
else
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.screenUpdateFlags(Update::Force | Update::FitCursor);
|
2004-02-20 17:19:53 +00:00
|
|
|
}
|
|
|
|
|
2002-08-20 13:00:25 +00:00
|
|
|
|
2007-04-29 23:33:02 +00:00
|
|
|
bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
|
2004-12-02 11:32:14 +00:00
|
|
|
FuncStatus & flag) const
|
2004-02-20 17:19:53 +00:00
|
|
|
{
|
2013-04-27 21:52:55 +00:00
|
|
|
LBUFERR(this == cur.text());
|
2005-11-02 11:27:08 +00:00
|
|
|
|
2008-10-19 09:23:46 +00:00
|
|
|
FontInfo const & fontinfo = cur.real_current_font.fontInfo();
|
2004-03-18 13:57:20 +00:00
|
|
|
bool enable = true;
|
2012-11-20 15:58:51 +00:00
|
|
|
bool allow_in_passthru = false;
|
2007-10-13 09:04:52 +00:00
|
|
|
InsetCode code = NO_CODE;
|
2004-03-18 13:57:20 +00:00
|
|
|
|
2010-04-09 19:00:42 +00:00
|
|
|
switch (cmd.action()) {
|
2004-03-18 13:57:20 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_DEPTH_DECREMENT:
|
2004-03-18 13:57:20 +00:00
|
|
|
enable = changeDepthAllowed(cur, DEC_DEPTH);
|
|
|
|
break;
|
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_DEPTH_INCREMENT:
|
2004-03-18 13:57:20 +00:00
|
|
|
enable = changeDepthAllowed(cur, INC_DEPTH);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LFUN_APPENDIX:
|
2012-07-21 18:18:52 +00:00
|
|
|
// FIXME We really should not allow this to be put, e.g.,
|
2014-03-14 13:22:26 +00:00
|
|
|
// in a footnote, or in ERT. But it would make sense in a
|
2012-07-21 18:18:52 +00:00
|
|
|
// branch, so I'm not sure what to do.
|
2004-03-18 13:57:20 +00:00
|
|
|
flag.setOnOff(cur.paragraph().params().startOfAppendix());
|
2008-05-26 10:23:07 +00:00
|
|
|
break;
|
2004-03-18 13:57:20 +00:00
|
|
|
|
|
|
|
case LFUN_DIALOG_SHOW_NEW_INSET:
|
2006-09-01 15:41:38 +00:00
|
|
|
if (cmd.argument() == "bibitem")
|
2007-10-13 09:04:52 +00:00
|
|
|
code = BIBITEM_CODE;
|
2009-05-09 16:53:51 +00:00
|
|
|
else if (cmd.argument() == "bibtex") {
|
2007-10-13 09:04:52 +00:00
|
|
|
code = BIBTEX_CODE;
|
2009-05-09 16:53:51 +00:00
|
|
|
// not allowed in description items
|
|
|
|
enable = !inDescriptionItem(cur);
|
|
|
|
}
|
2006-09-01 15:41:38 +00:00
|
|
|
else if (cmd.argument() == "box")
|
2007-10-13 09:04:52 +00:00
|
|
|
code = BOX_CODE;
|
2006-09-01 15:41:38 +00:00
|
|
|
else if (cmd.argument() == "branch")
|
2007-10-13 09:04:52 +00:00
|
|
|
code = BRANCH_CODE;
|
2006-09-01 15:41:38 +00:00
|
|
|
else if (cmd.argument() == "citation")
|
2007-10-13 09:04:52 +00:00
|
|
|
code = CITE_CODE;
|
2006-09-01 15:41:38 +00:00
|
|
|
else if (cmd.argument() == "ert")
|
2007-10-13 09:04:52 +00:00
|
|
|
code = ERT_CODE;
|
2006-09-01 15:41:38 +00:00
|
|
|
else if (cmd.argument() == "external")
|
2007-10-13 09:04:52 +00:00
|
|
|
code = EXTERNAL_CODE;
|
2006-09-01 15:41:38 +00:00
|
|
|
else if (cmd.argument() == "float")
|
2007-10-13 09:04:52 +00:00
|
|
|
code = FLOAT_CODE;
|
2006-09-01 15:41:38 +00:00
|
|
|
else if (cmd.argument() == "graphics")
|
2007-10-13 09:04:52 +00:00
|
|
|
code = GRAPHICS_CODE;
|
2007-10-13 19:06:09 +00:00
|
|
|
else if (cmd.argument() == "href")
|
|
|
|
code = HYPERLINK_CODE;
|
2006-09-01 15:41:38 +00:00
|
|
|
else if (cmd.argument() == "include")
|
2007-10-13 09:04:52 +00:00
|
|
|
code = INCLUDE_CODE;
|
2006-09-01 15:41:38 +00:00
|
|
|
else if (cmd.argument() == "index")
|
2007-10-13 09:04:52 +00:00
|
|
|
code = INDEX_CODE;
|
2009-04-17 14:29:32 +00:00
|
|
|
else if (cmd.argument() == "index_print")
|
|
|
|
code = INDEX_PRINT_CODE;
|
2014-03-04 10:56:03 +00:00
|
|
|
else if (cmd.argument() == "listings")
|
|
|
|
code = LISTINGS_CODE;
|
|
|
|
else if (cmd.argument() == "mathspace")
|
|
|
|
code = MATH_HULL_CODE;
|
2006-11-04 17:55:36 +00:00
|
|
|
else if (cmd.argument() == "nomenclature")
|
2007-10-13 09:04:52 +00:00
|
|
|
code = NOMENCL_CODE;
|
2009-05-22 16:26:15 +00:00
|
|
|
else if (cmd.argument() == "nomencl_print")
|
|
|
|
code = NOMENCL_PRINT_CODE;
|
2006-09-01 15:41:38 +00:00
|
|
|
else if (cmd.argument() == "label")
|
2007-10-13 09:04:52 +00:00
|
|
|
code = LABEL_CODE;
|
2010-09-07 00:41:00 +00:00
|
|
|
else if (cmd.argument() == "line")
|
|
|
|
code = LINE_CODE;
|
2006-09-01 15:41:38 +00:00
|
|
|
else if (cmd.argument() == "note")
|
2007-10-13 09:04:52 +00:00
|
|
|
code = NOTE_CODE;
|
2009-01-30 00:56:37 +00:00
|
|
|
else if (cmd.argument() == "phantom")
|
|
|
|
code = PHANTOM_CODE;
|
2006-09-01 15:41:38 +00:00
|
|
|
else if (cmd.argument() == "ref")
|
2007-10-13 09:04:52 +00:00
|
|
|
code = REF_CODE;
|
*** File Format Change: UI and enhancement for InsetSpace ***
* src/insets/InsetSpace.{cpp,h}:
- merge in HFill inset, add support for dotfill, hrulefill,
hspace and hspace*
* src/insets/InsetHFill.{cpp,h}:
- remove
* src/frontends/qt4/GuiHSpace.{cpp,h}:
* src/frontends/qt4/ui/HSpaceUi.ui:
* src/frontends/qt4/GuiView:
- new GUI for Space insets.
* src/insets/Inset.{cpp,h}:
* src/insets/InsetCode.h:
* src/insets/InsetCollapsable.cpp:
* src/insets/InsetCommandParams.cpp:
- remove HFILL_CODE and LFUN_HFILL_INSERT, add SPACE_CODE where necessary,
new Inset member isStretchableSpace() to indicate HFill and friends.
* Buffer.cpp:
- increase format to 319
* lib/lyx2lyx/LyX.py:
* lib/lyx2lyx/lyx_1_6.py:
- conversion/reversion routines
* development/FORMAT:
- document file format change
* src/Makefile.am:
* src/frontends/qt4/Makefile.am:
* development/scons/scons_manifest.py:
- deal with UI changes.
* src/LyXAction.cpp:
- remove LFUN_HFILL_INSERT
* src/LyXFunc.cpp:
- handle space dialog.
* src/factory.cpp:
* src/Paragraph.cpp (isHFill):
* src/Text.cpp:
* src/Text3.cpp:
* src/TextMetrics.cpp:
- adapt to changes
* lib/ui/classic.ui:
* lib/ui/stdmenus.ui:
- add HSpace dialog, remove HFill.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@23787 a592a061-630c-0410-9148-cb99ea01b6c8
2008-03-17 09:23:43 +00:00
|
|
|
else if (cmd.argument() == "space")
|
|
|
|
code = SPACE_CODE;
|
2006-09-01 15:41:38 +00:00
|
|
|
else if (cmd.argument() == "toc")
|
2007-10-13 09:04:52 +00:00
|
|
|
code = TOC_CODE;
|
2006-09-01 15:41:38 +00:00
|
|
|
else if (cmd.argument() == "vspace")
|
2007-10-13 09:04:52 +00:00
|
|
|
code = VSPACE_CODE;
|
2006-09-01 15:41:38 +00:00
|
|
|
else if (cmd.argument() == "wrap")
|
2007-10-13 09:04:52 +00:00
|
|
|
code = WRAP_CODE;
|
2004-03-18 13:57:20 +00:00
|
|
|
break;
|
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_ERT_INSERT:
|
2007-10-13 09:04:52 +00:00
|
|
|
code = ERT_CODE;
|
2004-03-18 13:57:20 +00:00
|
|
|
break;
|
Add support for listings package. Two listings command \lstinline, \lstinputlisting and an environment \lstlisting are supported, along with preamble \lstset. \lstinputlisting is implemented through Include dialog, and the other two are implemented with a new inset listings, along with its dialog.
* src/LyXAction.cpp: listing-insert action
* src/insets/Inset.h,cpp: LISTINGS_CODE
* src/insets/InsetInclude.cpp: handle \lstinputlisting
* src/insets/InsetListings.h,cpp: new listings inset
* src/insets/InsetListingsParams.h,cpp: parameters from listings package
* src/insets/InsetCommandParams.h,cpp: handle lstinputlisting option
* src/Bidi.cpp: handle LISTINGS_CODE
* src/frontends/qt4/ui/TextLayoutUi.ui: update UI
* src/frontends/qt4/ui/ListingsUi.ui: new dialog
* src/frontends/qt4/ui/IncludeUi.ui: update UI
* src/frontends/qt4/QInclude.h,cpp: add lstinputlisting
* src/frontends/qt4/QDocument.h,cpp: add textedit for preamble listings_params
* src/frontends/qt4/QListings.h,cpp: new listings inset
* src/frontends/qt4/Dialogs.cpp: new listings dialog
* src/frontends/controllers/ControlInclude.h,cpp: add lstinputlisting
* src/frontends/controllers/ControlListings.h,cpp: new listings inset
* src/LyXFunc.cpp: handle LISTING_CODE
* src/Paragraph.cpp: handle LISTING_CODE
* src/factory.cpp: new listings inset
* src/CutAndPaste.cpp: handle LISTINGS_CODE
* src/LaTeXFeatures.cpp: require listings
* src/Text3.cpp: Handle LISTINGS_CODE
* src/lfuns.h: add LFUN_LISTING_INSERT
* src/Buffer.cpp: change lyx file format to 269
* src/BufferParams.h,cpp: add listings_params to preamble
* lib/lyx2lyx/LyX.py: lyx2lyx
* lib/lyx2lyx/lyx_1_5.py: lyx2lyx
* lib/ui/stdmenus.inc: new menu item (no shortcut!)
* src/insets/Makefile.am: update autotools
* src/frontends/controllers/Makefile.am
* src/frontends/qt4/Makefile.dialogs
* src/frontends/qt4/Makefile.am
* po/POTFILES.in: a few more translatable files.
* development/scons/scons_manifest.py: scons build system
* development/FORMAT: document format changes
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@18243 a592a061-630c-0410-9148-cb99ea01b6c8
2007-05-09 19:11:42 +00:00
|
|
|
case LFUN_LISTING_INSERT:
|
2008-03-24 13:20:06 +00:00
|
|
|
code = LISTINGS_CODE;
|
2008-10-14 13:27:58 +00:00
|
|
|
// not allowed in description items
|
|
|
|
enable = !inDescriptionItem(cur);
|
Add support for listings package. Two listings command \lstinline, \lstinputlisting and an environment \lstlisting are supported, along with preamble \lstset. \lstinputlisting is implemented through Include dialog, and the other two are implemented with a new inset listings, along with its dialog.
* src/LyXAction.cpp: listing-insert action
* src/insets/Inset.h,cpp: LISTINGS_CODE
* src/insets/InsetInclude.cpp: handle \lstinputlisting
* src/insets/InsetListings.h,cpp: new listings inset
* src/insets/InsetListingsParams.h,cpp: parameters from listings package
* src/insets/InsetCommandParams.h,cpp: handle lstinputlisting option
* src/Bidi.cpp: handle LISTINGS_CODE
* src/frontends/qt4/ui/TextLayoutUi.ui: update UI
* src/frontends/qt4/ui/ListingsUi.ui: new dialog
* src/frontends/qt4/ui/IncludeUi.ui: update UI
* src/frontends/qt4/QInclude.h,cpp: add lstinputlisting
* src/frontends/qt4/QDocument.h,cpp: add textedit for preamble listings_params
* src/frontends/qt4/QListings.h,cpp: new listings inset
* src/frontends/qt4/Dialogs.cpp: new listings dialog
* src/frontends/controllers/ControlInclude.h,cpp: add lstinputlisting
* src/frontends/controllers/ControlListings.h,cpp: new listings inset
* src/LyXFunc.cpp: handle LISTING_CODE
* src/Paragraph.cpp: handle LISTING_CODE
* src/factory.cpp: new listings inset
* src/CutAndPaste.cpp: handle LISTINGS_CODE
* src/LaTeXFeatures.cpp: require listings
* src/Text3.cpp: Handle LISTINGS_CODE
* src/lfuns.h: add LFUN_LISTING_INSERT
* src/Buffer.cpp: change lyx file format to 269
* src/BufferParams.h,cpp: add listings_params to preamble
* lib/lyx2lyx/LyX.py: lyx2lyx
* lib/lyx2lyx/lyx_1_5.py: lyx2lyx
* lib/ui/stdmenus.inc: new menu item (no shortcut!)
* src/insets/Makefile.am: update autotools
* src/frontends/controllers/Makefile.am
* src/frontends/qt4/Makefile.dialogs
* src/frontends/qt4/Makefile.am
* po/POTFILES.in: a few more translatable files.
* development/scons/scons_manifest.py: scons build system
* development/FORMAT: document format changes
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@18243 a592a061-630c-0410-9148-cb99ea01b6c8
2007-05-09 19:11:42 +00:00
|
|
|
break;
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FOOTNOTE_INSERT:
|
2007-10-13 09:04:52 +00:00
|
|
|
code = FOOT_CODE;
|
2004-03-18 13:57:20 +00:00
|
|
|
break;
|
|
|
|
case LFUN_TABULAR_INSERT:
|
2007-10-13 09:04:52 +00:00
|
|
|
code = TABULAR_CODE;
|
2004-03-18 13:57:20 +00:00
|
|
|
break;
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_MARGINALNOTE_INSERT:
|
2007-10-13 09:04:52 +00:00
|
|
|
code = MARGIN_CODE;
|
2004-03-18 13:57:20 +00:00
|
|
|
break;
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FLOAT_INSERT:
|
|
|
|
case LFUN_FLOAT_WIDE_INSERT:
|
2009-07-21 20:04:52 +00:00
|
|
|
// FIXME: If there is a selection, we should check whether there
|
|
|
|
// are floats in the selection, but this has performance issues, see
|
|
|
|
// LFUN_CHANGE_ACCEPT/REJECT.
|
2007-10-13 09:04:52 +00:00
|
|
|
code = FLOAT_CODE;
|
2009-07-21 20:04:52 +00:00
|
|
|
if (inDescriptionItem(cur))
|
|
|
|
// not allowed in description items
|
|
|
|
enable = false;
|
|
|
|
else {
|
|
|
|
InsetCode const inset_code = cur.inset().lyxCode();
|
|
|
|
|
|
|
|
// algorithm floats cannot be put in another float
|
|
|
|
if (to_utf8(cmd.argument()) == "algorithm") {
|
|
|
|
enable = inset_code != WRAP_CODE && inset_code != FLOAT_CODE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// for figures and tables: only allow in another
|
|
|
|
// float or wrap if it is of the same type and
|
|
|
|
// not a subfloat already
|
|
|
|
if(cur.inset().lyxCode() == code) {
|
|
|
|
InsetFloat const & ins =
|
|
|
|
static_cast<InsetFloat const &>(cur.inset());
|
|
|
|
enable = ins.params().type == to_utf8(cmd.argument())
|
|
|
|
&& !ins.params().subfloat;
|
|
|
|
} else if(cur.inset().lyxCode() == WRAP_CODE) {
|
|
|
|
InsetWrap const & ins =
|
|
|
|
static_cast<InsetWrap const &>(cur.inset());
|
|
|
|
enable = ins.params().type == to_utf8(cmd.argument());
|
|
|
|
}
|
|
|
|
}
|
2004-03-18 13:57:20 +00:00
|
|
|
break;
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_WRAP_INSERT:
|
2007-10-13 09:04:52 +00:00
|
|
|
code = WRAP_CODE;
|
2008-10-14 13:27:58 +00:00
|
|
|
// not allowed in description items
|
|
|
|
enable = !inDescriptionItem(cur);
|
2004-03-18 13:57:20 +00:00
|
|
|
break;
|
2010-03-05 23:47:33 +00:00
|
|
|
case LFUN_FLOAT_LIST_INSERT: {
|
2007-10-13 09:04:52 +00:00
|
|
|
code = FLOAT_LIST_CODE;
|
2009-05-09 16:53:51 +00:00
|
|
|
// not allowed in description items
|
|
|
|
enable = !inDescriptionItem(cur);
|
2010-03-05 23:47:33 +00:00
|
|
|
if (enable) {
|
|
|
|
FloatList const & floats = cur.buffer()->params().documentClass().floats();
|
|
|
|
FloatList::const_iterator cit = floats[to_ascii(cmd.argument())];
|
|
|
|
// make sure we know about such floats
|
|
|
|
if (cit == floats.end() ||
|
|
|
|
// and that we know how to generate a list of them
|
2011-02-02 22:15:52 +00:00
|
|
|
(!cit->second.usesFloatPkg() && cit->second.listCommand().empty())) {
|
2010-04-16 10:51:20 +00:00
|
|
|
flag.setUnknown(true);
|
2010-03-05 23:47:33 +00:00
|
|
|
// probably not necessary, but...
|
|
|
|
enable = false;
|
|
|
|
}
|
|
|
|
}
|
2004-03-18 13:57:20 +00:00
|
|
|
break;
|
2010-03-05 23:47:33 +00:00
|
|
|
}
|
2012-12-30 17:29:02 +00:00
|
|
|
case LFUN_CAPTION_INSERT: {
|
2007-10-13 09:04:52 +00:00
|
|
|
code = CAPTION_CODE;
|
2013-03-22 21:23:38 +00:00
|
|
|
string arg = cmd.getArg(0);
|
2016-03-25 18:22:57 +00:00
|
|
|
bool varia = arg != "Unnumbered"
|
2014-11-27 17:51:26 +00:00
|
|
|
&& cur.inset().allowsCaptionVariation(arg);
|
2012-12-30 17:29:02 +00:00
|
|
|
// not allowed in description items,
|
|
|
|
// and in specific insets
|
|
|
|
enable = !inDescriptionItem(cur)
|
|
|
|
&& (varia || arg.empty() || arg == "Standard");
|
2004-03-18 13:57:20 +00:00
|
|
|
break;
|
2012-12-30 17:29:02 +00:00
|
|
|
}
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_NOTE_INSERT:
|
2007-10-13 09:04:52 +00:00
|
|
|
code = NOTE_CODE;
|
2008-10-14 13:27:58 +00:00
|
|
|
// in commands (sections etc.) and description items,
|
|
|
|
// only Notes are allowed
|
2008-03-24 13:20:06 +00:00
|
|
|
enable = (cmd.argument().empty() || cmd.getArg(0) == "Note" ||
|
2008-10-14 13:27:58 +00:00
|
|
|
(!cur.paragraph().layout().isCommand()
|
|
|
|
&& !inDescriptionItem(cur)));
|
2004-03-18 13:57:20 +00:00
|
|
|
break;
|
2007-09-08 13:11:10 +00:00
|
|
|
case LFUN_FLEX_INSERT: {
|
2007-10-13 09:04:52 +00:00
|
|
|
code = FLEX_CODE;
|
2007-09-08 13:11:10 +00:00
|
|
|
string s = cmd.getArg(0);
|
2008-10-13 11:25:37 +00:00
|
|
|
InsetLayout il =
|
2008-11-17 11:46:07 +00:00
|
|
|
cur.buffer()->params().documentClass().insetLayout(from_utf8(s));
|
2008-10-25 13:32:54 +00:00
|
|
|
if (il.lyxtype() != InsetLayout::CHARSTYLE &&
|
|
|
|
il.lyxtype() != InsetLayout::CUSTOM &&
|
|
|
|
il.lyxtype() != InsetLayout::ELEMENT &&
|
|
|
|
il.lyxtype ()!= InsetLayout::STANDARD)
|
2004-03-18 13:57:20 +00:00
|
|
|
enable = false;
|
|
|
|
break;
|
2007-09-08 13:11:10 +00:00
|
|
|
}
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_BOX_INSERT:
|
2007-10-13 09:04:52 +00:00
|
|
|
code = BOX_CODE;
|
2004-03-18 13:57:20 +00:00
|
|
|
break;
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_BRANCH_INSERT:
|
2007-10-13 09:04:52 +00:00
|
|
|
code = BRANCH_CODE;
|
2009-05-08 12:38:58 +00:00
|
|
|
if (cur.buffer()->masterBuffer()->params().branchlist().empty()
|
2009-05-08 15:12:28 +00:00
|
|
|
&& cur.buffer()->params().branchlist().empty())
|
2004-03-18 13:57:20 +00:00
|
|
|
enable = false;
|
|
|
|
break;
|
2012-03-06 07:54:22 +00:00
|
|
|
case LFUN_IPA_INSERT:
|
|
|
|
code = IPA_CODE;
|
|
|
|
break;
|
2009-01-30 00:56:37 +00:00
|
|
|
case LFUN_PHANTOM_INSERT:
|
|
|
|
code = PHANTOM_CODE;
|
|
|
|
break;
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_LABEL_INSERT:
|
2007-10-13 09:04:52 +00:00
|
|
|
code = LABEL_CODE;
|
2009-07-14 21:56:22 +00:00
|
|
|
break;
|
2007-10-11 14:52:00 +00:00
|
|
|
case LFUN_INFO_INSERT:
|
2007-10-13 09:04:52 +00:00
|
|
|
code = INFO_CODE;
|
2007-10-11 14:52:00 +00:00
|
|
|
break;
|
2010-06-04 22:53:44 +00:00
|
|
|
case LFUN_ARGUMENT_INSERT: {
|
2010-06-04 22:44:58 +00:00
|
|
|
code = ARG_CODE;
|
2012-11-20 15:58:51 +00:00
|
|
|
allow_in_passthru = true;
|
2012-11-19 13:21:02 +00:00
|
|
|
string const arg = cmd.getArg(0);
|
|
|
|
if (arg.empty()) {
|
|
|
|
enable = false;
|
|
|
|
break;
|
|
|
|
}
|
2010-06-04 21:50:08 +00:00
|
|
|
Layout const & lay = cur.paragraph().layout();
|
2012-12-16 13:10:03 +00:00
|
|
|
Layout::LaTeXArgMap args = lay.args();
|
2012-11-19 13:21:02 +00:00
|
|
|
Layout::LaTeXArgMap::const_iterator const lait =
|
2012-11-29 14:34:20 +00:00
|
|
|
args.find(arg);
|
2012-11-19 13:21:02 +00:00
|
|
|
if (lait != args.end()) {
|
2012-11-20 14:48:59 +00:00
|
|
|
enable = true;
|
2012-12-10 08:19:56 +00:00
|
|
|
pit_type pit = cur.pit();
|
|
|
|
pit_type lastpit = cur.pit();
|
|
|
|
if (lay.isEnvironment() && !prefixIs(arg, "item:")) {
|
|
|
|
// In a sequence of "merged" environment layouts, we only allow
|
|
|
|
// non-item arguments once.
|
|
|
|
lastpit = cur.lastpit();
|
|
|
|
// get the first paragraph in sequence with this layout
|
|
|
|
depth_type const current_depth = cur.paragraph().params().depth();
|
|
|
|
while (true) {
|
|
|
|
if (pit == 0)
|
2012-11-19 13:21:02 +00:00
|
|
|
break;
|
2012-12-10 08:19:56 +00:00
|
|
|
Paragraph cpar = pars_[pit - 1];
|
|
|
|
if (cpar.layout() == lay && cpar.params().depth() == current_depth)
|
|
|
|
--pit;
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (; pit <= lastpit; ++pit) {
|
|
|
|
if (pars_[pit].layout() != lay)
|
|
|
|
break;
|
2017-05-12 21:13:38 +00:00
|
|
|
for (auto const & table : pars_[pit].insetList())
|
|
|
|
if (InsetArgument const * ins = table.inset->asInsetArgument())
|
2012-12-10 08:19:56 +00:00
|
|
|
if (ins->name() == arg) {
|
|
|
|
// we have this already
|
|
|
|
enable = false;
|
|
|
|
break;
|
|
|
|
}
|
2012-11-19 13:21:02 +00:00
|
|
|
}
|
|
|
|
} else
|
|
|
|
enable = false;
|
2004-03-18 13:57:20 +00:00
|
|
|
break;
|
2010-06-04 21:50:08 +00:00
|
|
|
}
|
2004-03-18 13:57:20 +00:00
|
|
|
case LFUN_INDEX_INSERT:
|
2007-10-13 09:04:52 +00:00
|
|
|
code = INDEX_CODE;
|
2004-03-18 13:57:20 +00:00
|
|
|
break;
|
|
|
|
case LFUN_INDEX_PRINT:
|
2007-10-13 09:04:52 +00:00
|
|
|
code = INDEX_PRINT_CODE;
|
2009-05-09 16:53:51 +00:00
|
|
|
// not allowed in description items
|
|
|
|
enable = !inDescriptionItem(cur);
|
2004-03-18 13:57:20 +00:00
|
|
|
break;
|
2006-11-04 17:55:36 +00:00
|
|
|
case LFUN_NOMENCL_INSERT:
|
2008-08-09 16:31:22 +00:00
|
|
|
if (cur.selIsMultiCell() || cur.selIsMultiLine()) {
|
|
|
|
enable = false;
|
|
|
|
break;
|
|
|
|
}
|
2007-10-13 09:04:52 +00:00
|
|
|
code = NOMENCL_CODE;
|
2006-11-04 17:55:36 +00:00
|
|
|
break;
|
|
|
|
case LFUN_NOMENCL_PRINT:
|
2007-10-13 09:04:52 +00:00
|
|
|
code = NOMENCL_PRINT_CODE;
|
2009-05-09 16:53:51 +00:00
|
|
|
// not allowed in description items
|
|
|
|
enable = !inDescriptionItem(cur);
|
2006-11-04 17:55:36 +00:00
|
|
|
break;
|
2014-02-11 10:00:20 +00:00
|
|
|
case LFUN_HREF_INSERT:
|
2008-08-09 16:15:49 +00:00
|
|
|
if (cur.selIsMultiCell() || cur.selIsMultiLine()) {
|
2008-08-09 02:09:38 +00:00
|
|
|
enable = false;
|
|
|
|
break;
|
|
|
|
}
|
2007-10-13 19:06:09 +00:00
|
|
|
code = HYPERLINK_CODE;
|
2004-03-18 13:57:20 +00:00
|
|
|
break;
|
2012-08-23 15:42:53 +00:00
|
|
|
case LFUN_IPAMACRO_INSERT: {
|
|
|
|
string const arg = cmd.getArg(0);
|
|
|
|
if (arg == "deco")
|
|
|
|
code = IPADECO_CODE;
|
|
|
|
else
|
|
|
|
code = IPACHAR_CODE;
|
|
|
|
break;
|
|
|
|
}
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_QUOTE_INSERT:
|
2004-03-18 13:57:20 +00:00
|
|
|
// always allow this, since we will inset a raw quote
|
|
|
|
// if an inset is not allowed.
|
2016-12-10 10:53:42 +00:00
|
|
|
allow_in_passthru = true;
|
2004-03-18 13:57:20 +00:00
|
|
|
break;
|
2007-12-06 11:04:56 +00:00
|
|
|
case LFUN_SPECIALCHAR_INSERT:
|
2007-10-13 09:04:52 +00:00
|
|
|
code = SPECIALCHAR_CODE;
|
2004-03-18 13:57:20 +00:00
|
|
|
break;
|
|
|
|
case LFUN_SPACE_INSERT:
|
|
|
|
// slight hack: we know this is allowed in math mode
|
|
|
|
if (cur.inTexted())
|
2007-10-13 09:04:52 +00:00
|
|
|
code = SPACE_CODE;
|
2004-03-18 13:57:20 +00:00
|
|
|
break;
|
2010-03-28 13:47:50 +00:00
|
|
|
case LFUN_PREVIEW_INSERT:
|
|
|
|
code = PREVIEW_CODE;
|
|
|
|
break;
|
2010-11-23 20:09:08 +00:00
|
|
|
case LFUN_SCRIPT_INSERT:
|
|
|
|
code = SCRIPT_CODE;
|
|
|
|
break;
|
2005-11-02 11:27:08 +00:00
|
|
|
|
2009-07-14 21:56:22 +00:00
|
|
|
case LFUN_MATH_INSERT:
|
|
|
|
case LFUN_MATH_AMS_MATRIX:
|
|
|
|
case LFUN_MATH_MATRIX:
|
|
|
|
case LFUN_MATH_DELIM:
|
|
|
|
case LFUN_MATH_BIGDELIM:
|
|
|
|
case LFUN_MATH_DISPLAY:
|
|
|
|
case LFUN_MATH_MODE:
|
|
|
|
case LFUN_MATH_MACRO:
|
|
|
|
case LFUN_MATH_SUBSCRIPT:
|
|
|
|
case LFUN_MATH_SUPERSCRIPT:
|
2009-07-16 19:00:24 +00:00
|
|
|
code = MATH_HULL_CODE;
|
2009-07-14 21:56:22 +00:00
|
|
|
break;
|
|
|
|
|
2010-02-08 11:19:48 +00:00
|
|
|
case LFUN_REGEXP_MODE:
|
|
|
|
code = MATH_HULL_CODE;
|
|
|
|
enable = cur.buffer()->isInternal() && !cur.inRegexped();
|
|
|
|
break;
|
|
|
|
|
2005-04-13 09:43:58 +00:00
|
|
|
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;
|
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_EMPH:
|
2007-10-28 18:51:54 +00:00
|
|
|
flag.setOnOff(fontinfo.emph() == FONT_ON);
|
2011-01-26 11:04:42 +00:00
|
|
|
enable = !cur.paragraph().isPassThru();
|
2008-05-25 21:01:27 +00:00
|
|
|
break;
|
2004-03-18 13:57:20 +00:00
|
|
|
|
2008-11-26 18:47:52 +00:00
|
|
|
case LFUN_FONT_ITAL:
|
|
|
|
flag.setOnOff(fontinfo.shape() == ITALIC_SHAPE);
|
2011-01-26 11:04:42 +00:00
|
|
|
enable = !cur.paragraph().isPassThru();
|
2008-11-26 18:47:52 +00:00
|
|
|
break;
|
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_NOUN:
|
2007-10-28 18:51:54 +00:00
|
|
|
flag.setOnOff(fontinfo.noun() == FONT_ON);
|
2011-01-26 11:04:42 +00:00
|
|
|
enable = !cur.paragraph().isPassThru();
|
2008-05-25 21:01:27 +00:00
|
|
|
break;
|
2004-03-18 13:57:20 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_BOLD:
|
2008-09-15 16:49:11 +00:00
|
|
|
case LFUN_FONT_BOLDSYMBOL:
|
2007-10-28 18:51:54 +00:00
|
|
|
flag.setOnOff(fontinfo.series() == BOLD_SERIES);
|
2011-01-26 11:04:42 +00:00
|
|
|
enable = !cur.paragraph().isPassThru();
|
2008-05-25 21:01:27 +00:00
|
|
|
break;
|
2004-03-18 13:57:20 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_SANS:
|
2007-10-28 18:51:54 +00:00
|
|
|
flag.setOnOff(fontinfo.family() == SANS_FAMILY);
|
2011-01-26 11:04:42 +00:00
|
|
|
enable = !cur.paragraph().isPassThru();
|
2008-05-25 21:01:27 +00:00
|
|
|
break;
|
2004-03-18 13:57:20 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_ROMAN:
|
2007-10-28 18:51:54 +00:00
|
|
|
flag.setOnOff(fontinfo.family() == ROMAN_FAMILY);
|
2011-01-26 11:04:42 +00:00
|
|
|
enable = !cur.paragraph().isPassThru();
|
2008-05-25 21:01:27 +00:00
|
|
|
break;
|
2004-03-18 13:57:20 +00:00
|
|
|
|
2007-09-20 18:02:39 +00:00
|
|
|
case LFUN_FONT_TYPEWRITER:
|
2007-10-28 18:51:54 +00:00
|
|
|
flag.setOnOff(fontinfo.family() == TYPEWRITER_FAMILY);
|
2011-01-26 11:04:42 +00:00
|
|
|
enable = !cur.paragraph().isPassThru();
|
2008-05-25 21:01:27 +00:00
|
|
|
break;
|
2004-03-18 13:57:20 +00:00
|
|
|
|
2005-11-25 09:27:08 +00:00
|
|
|
case LFUN_CUT:
|
|
|
|
case LFUN_COPY:
|
|
|
|
enable = cur.selection();
|
|
|
|
break;
|
|
|
|
|
2008-02-03 10:43:03 +00:00
|
|
|
case LFUN_PASTE: {
|
2007-01-04 12:05:24 +00:00
|
|
|
if (cmd.argument().empty()) {
|
|
|
|
if (theClipboard().isInternal())
|
|
|
|
enable = cap::numberOfSelections() > 0;
|
|
|
|
else
|
2007-01-07 16:43:38 +00:00
|
|
|
enable = !theClipboard().empty();
|
2008-02-03 10:43:03 +00:00
|
|
|
break;
|
|
|
|
}
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2008-02-03 10:43:03 +00:00
|
|
|
// we have an argument
|
|
|
|
string const arg = to_utf8(cmd.argument());
|
|
|
|
if (isStrUnsignedInt(arg)) {
|
|
|
|
// it's a number and therefore means the internal stack
|
|
|
|
unsigned int n = convert<unsigned int>(arg);
|
|
|
|
enable = cap::numberOfSelections() > n;
|
|
|
|
break;
|
2007-01-07 16:43:38 +00:00
|
|
|
}
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2013-04-14 17:45:36 +00:00
|
|
|
// explicit text type?
|
|
|
|
if (arg == "html") {
|
|
|
|
// Do not enable for PlainTextType, since some tidying in the
|
|
|
|
// frontend is needed for HTML, which is too unsafe for plain text.
|
|
|
|
enable = theClipboard().hasTextContents(Clipboard::HtmlTextType);
|
|
|
|
break;
|
|
|
|
} else if (arg == "latex") {
|
|
|
|
// LaTeX is usually not available on the clipboard with
|
|
|
|
// the correct MIME type, but in plain text.
|
|
|
|
enable = theClipboard().hasTextContents(Clipboard::PlainTextType) ||
|
|
|
|
theClipboard().hasTextContents(Clipboard::LaTeXTextType);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2009-05-03 11:22:01 +00:00
|
|
|
Clipboard::GraphicsType type = Clipboard::AnyGraphicsType;
|
2015-05-09 03:26:57 +00:00
|
|
|
if (arg == "pdf")
|
|
|
|
type = Clipboard::PdfGraphicsType;
|
|
|
|
else if (arg == "png")
|
|
|
|
type = Clipboard::PngGraphicsType;
|
|
|
|
else if (arg == "jpeg")
|
|
|
|
type = Clipboard::JpegGraphicsType;
|
|
|
|
else if (arg == "linkback")
|
|
|
|
type = Clipboard::LinkBackGraphicsType;
|
|
|
|
else if (arg == "emf")
|
|
|
|
type = Clipboard::EmfGraphicsType;
|
|
|
|
else if (arg == "wmf")
|
|
|
|
type = Clipboard::WmfGraphicsType;
|
|
|
|
else {
|
|
|
|
// unknown argument
|
|
|
|
LYXERR0("Unrecognized graphics type: " << arg);
|
|
|
|
// we don't want to assert if the user just mistyped the LFUN
|
|
|
|
LATTEST(cmd.origin() != FuncRequest::INTERNAL);
|
|
|
|
enable = false;
|
2008-02-03 10:43:03 +00:00
|
|
|
break;
|
|
|
|
}
|
2015-05-09 03:26:57 +00:00
|
|
|
enable = theClipboard().hasGraphicsContents(type);
|
2007-01-07 16:43:38 +00:00
|
|
|
break;
|
2015-05-09 03:26:57 +00:00
|
|
|
}
|
2007-01-07 16:43:38 +00:00
|
|
|
|
|
|
|
case LFUN_CLIPBOARD_PASTE:
|
2011-10-29 15:42:01 +00:00
|
|
|
case LFUN_CLIPBOARD_PASTE_SIMPLE:
|
2007-01-07 16:43:38 +00:00
|
|
|
enable = !theClipboard().empty();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LFUN_PRIMARY_SELECTION_PASTE:
|
2007-01-08 18:37:40 +00:00
|
|
|
enable = cur.selection() || !theSelection().empty();
|
2005-11-25 09:27:08 +00:00
|
|
|
break;
|
|
|
|
|
2009-01-14 14:24:59 +00:00
|
|
|
case LFUN_SELECTION_PASTE:
|
|
|
|
enable = cap::selection();
|
|
|
|
break;
|
|
|
|
|
2006-09-08 14:08:26 +00:00
|
|
|
case LFUN_PARAGRAPH_MOVE_UP:
|
2006-04-26 22:43:26 +00:00
|
|
|
enable = cur.pit() > 0 && !cur.selection();
|
|
|
|
break;
|
|
|
|
|
2006-09-08 14:08:26 +00:00
|
|
|
case LFUN_PARAGRAPH_MOVE_DOWN:
|
2006-04-26 22:43:26 +00:00
|
|
|
enable = cur.pit() < cur.lastpit() && !cur.selection();
|
|
|
|
break;
|
|
|
|
|
2006-10-04 21:43:40 +00:00
|
|
|
case LFUN_CHANGE_ACCEPT:
|
|
|
|
case LFUN_CHANGE_REJECT:
|
2006-11-24 23:01:24 +00:00
|
|
|
// In principle, these LFUNs should only be enabled if there
|
|
|
|
// is a change at the current position/in the current selection.
|
|
|
|
// However, without proper optimizations, this will inevitably
|
|
|
|
// result in unacceptable performance - just imagine a user who
|
|
|
|
// wants to select the complete content of a long document.
|
2009-08-04 23:01:06 +00:00
|
|
|
if (!cur.selection())
|
|
|
|
enable = cur.paragraph().isChanged(cur.pos());
|
|
|
|
else
|
2009-05-01 17:06:36 +00:00
|
|
|
// TODO: context-sensitive enabling of LFUN_CHANGE_ACCEPT/REJECT
|
|
|
|
// for selections.
|
|
|
|
enable = true;
|
2006-10-04 21:43:40 +00:00
|
|
|
break;
|
|
|
|
|
2007-11-06 17:13:43 +00:00
|
|
|
case LFUN_OUTLINE_UP:
|
|
|
|
case LFUN_OUTLINE_DOWN:
|
|
|
|
case LFUN_OUTLINE_IN:
|
|
|
|
case LFUN_OUTLINE_OUT:
|
2010-01-26 16:57:29 +00:00
|
|
|
// FIXME: LyX is not ready for outlining within inset.
|
|
|
|
enable = isMainText()
|
2012-12-15 15:47:57 +00:00
|
|
|
&& cur.buffer()->text().getTocLevel(cur.pit()) != Layout::NOT_IN_TOC;
|
2010-01-26 16:57:29 +00:00
|
|
|
break;
|
2007-11-06 17:13:43 +00:00
|
|
|
|
2008-03-26 08:10:01 +00:00
|
|
|
case LFUN_NEWLINE_INSERT:
|
|
|
|
// LaTeX restrictions (labels or empty par)
|
2014-03-04 10:56:03 +00:00
|
|
|
enable = !cur.paragraph().isPassThru()
|
|
|
|
&& cur.pos() > cur.paragraph().beginOfBody();
|
2008-03-26 08:10:01 +00:00
|
|
|
break;
|
|
|
|
|
Fix bugs #8546 and #9055, and introduce new separator inset.
The algorithm used for breaking a paragraph in LaTeX export is changed
for avoiding spurious blank lines causing too much vertical space.
This change is tied to the introduction of a new inset (with two
different specializations) helping in either outputing LaTeX paragraph
breaks or separating environments in LyX. Both of the above goals were
previously achieved by the ---Separator--- layout and can now be
accomplished by the new inset in a more natural way. As an example,
after leaving an environment by hitting the Return key for two times,
a third return automatically inserts a parbreak inset, which is
equivalent to the old separator layout, i.e., it also introduces a
blank line in the output. If this blank line is not wanted, the
parbreak separator can be changed to a plain separator by a right
click of the mouse. Of course, an environment can still be separated
by the following one by using the Alt+P+Return shortcut (or the
corresponding menu key), but now the plain separator inset is used
instead of the old separator layout, such that no blank line occurs in
the LaTeX output.
Old documents are converted such that the LaTeX output remains unchanged.
As a result of this conversion, the old separator layout is replaced by
the new parbreak inset, which may also appear in places where the old
algorithm was introducing blank lines while the new one is not.
Note that not all blank lines were actually affecting the LaTeX output,
because a blank line is simply ignored by the TeX engine when it occurs
in the so called "vertical mode" (e.g., after an alignment environment).
The old ---Separator--- layout is now gone and old layout files using it
are also automatically converted.
Round trip conversions between old and new format should leave a document
unchanged. This means that the new behavior about paragraph breaking is
not "carried back" to the old format. Indeed, this would need introducing
special LaTeX commands in ERT that would accumulate in roundtrip
conversions, horribly cluttering the document. So, when converting a
modified document to old formats, the LaTeX output may slightly differ in
vertical spacing if the document is processed by an old version of LyX.
In other words, forward compatibility is guaranteed, but not backwards.
2014-05-10 21:25:11 +00:00
|
|
|
case LFUN_SEPARATOR_INSERT:
|
|
|
|
// Always enabled for now
|
|
|
|
enable = true;
|
|
|
|
break;
|
|
|
|
|
2009-07-14 14:52:11 +00:00
|
|
|
case LFUN_TAB_INSERT:
|
|
|
|
case LFUN_TAB_DELETE:
|
2011-01-26 11:04:42 +00:00
|
|
|
enable = cur.paragraph().isPassThru();
|
2009-07-14 14:52:11 +00:00
|
|
|
break;
|
|
|
|
|
2008-05-26 09:08:30 +00:00
|
|
|
case LFUN_SET_GRAPHICS_GROUP: {
|
2008-05-27 12:06:34 +00:00
|
|
|
InsetGraphics * ins = graphics::getCurrentGraphicsInset(cur);
|
2008-10-13 11:25:37 +00:00
|
|
|
if (!ins)
|
2008-05-26 09:08:30 +00:00
|
|
|
enable = false;
|
|
|
|
else
|
|
|
|
flag.setOnOff(to_utf8(cmd.argument()) == ins->getParams().groupId);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2008-10-14 13:27:58 +00:00
|
|
|
case LFUN_NEWPAGE_INSERT:
|
|
|
|
// not allowed in description items
|
2009-07-14 21:56:22 +00:00
|
|
|
code = NEWPAGE_CODE;
|
2008-10-14 13:27:58 +00:00
|
|
|
enable = !inDescriptionItem(cur);
|
|
|
|
break;
|
|
|
|
|
2009-03-27 11:22:54 +00:00
|
|
|
case LFUN_DATE_INSERT: {
|
|
|
|
string const format = cmd.argument().empty()
|
|
|
|
? lyxrc.date_insert_format : to_utf8(cmd.argument());
|
|
|
|
enable = support::os::is_valid_strftime(format);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2009-07-14 15:27:48 +00:00
|
|
|
case LFUN_LANGUAGE:
|
2011-01-26 11:04:42 +00:00
|
|
|
enable = !cur.paragraph().isPassThru();
|
2012-10-03 05:27:36 +00:00
|
|
|
flag.setOnOff(cmd.getArg(0) == cur.real_current_font.language()->lang());
|
2009-10-29 22:08:05 +00:00
|
|
|
break;
|
2009-07-14 15:27:48 +00:00
|
|
|
|
2012-09-29 16:06:42 +00:00
|
|
|
case LFUN_PARAGRAPH_BREAK:
|
2015-03-30 21:12:39 +00:00
|
|
|
enable = inset().allowMultiPar();
|
2009-10-29 22:08:05 +00:00
|
|
|
break;
|
2014-03-14 13:22:26 +00:00
|
|
|
|
2010-01-19 08:21:56 +00:00
|
|
|
case LFUN_SPELLING_ADD:
|
|
|
|
case LFUN_SPELLING_IGNORE:
|
2010-08-05 20:10:40 +00:00
|
|
|
case LFUN_SPELLING_REMOVE:
|
2015-03-27 07:07:05 +00:00
|
|
|
enable = theSpellChecker() != NULL;
|
|
|
|
if (enable && !cmd.getArg(1).empty()) {
|
|
|
|
// validate explicitly given language
|
|
|
|
Language const * const lang = const_cast<Language *>(languages.getLanguage(cmd.getArg(1)));
|
|
|
|
enable &= lang != NULL;
|
|
|
|
}
|
2010-01-19 08:21:56 +00:00
|
|
|
break;
|
2009-07-14 15:27:48 +00:00
|
|
|
|
2015-03-17 15:40:55 +00:00
|
|
|
case LFUN_LAYOUT: {
|
2015-11-10 17:42:24 +00:00
|
|
|
DocumentClass const & tclass = cur.buffer()->params().documentClass();
|
2018-01-01 11:27:08 +00:00
|
|
|
bool const ignoreautonests = cmd.getArg(1) == "ignoreautonests";
|
|
|
|
docstring layout = ignoreautonests ? from_utf8(cmd.getArg(0)) : cmd.argument();
|
2015-11-10 17:42:24 +00:00
|
|
|
if (layout.empty())
|
2015-03-17 15:40:55 +00:00
|
|
|
layout = tclass.defaultLayoutName();
|
2016-05-12 12:10:30 +00:00
|
|
|
enable = !owner_->forcePlainLayout() && tclass.hasLayout(layout);
|
2015-11-10 17:42:24 +00:00
|
|
|
|
2015-03-17 15:40:55 +00:00
|
|
|
flag.setOnOff(layout == cur.paragraph().layout().name());
|
2010-02-08 11:19:48 +00:00
|
|
|
break;
|
2015-03-17 15:40:55 +00:00
|
|
|
}
|
2014-03-14 13:22:26 +00:00
|
|
|
|
2012-12-23 17:57:32 +00:00
|
|
|
case LFUN_ENVIRONMENT_SPLIT: {
|
2014-01-27 07:01:24 +00:00
|
|
|
if (cmd.argument() == "outer") {
|
|
|
|
// check if we have an environment in our nesting hierarchy
|
|
|
|
bool res = false;
|
|
|
|
depth_type const current_depth = cur.paragraph().params().depth();
|
|
|
|
pit_type pit = cur.pit();
|
|
|
|
Paragraph cpar = pars_[pit];
|
|
|
|
while (true) {
|
|
|
|
if (pit == 0 || cpar.params().depth() == 0)
|
|
|
|
break;
|
|
|
|
--pit;
|
|
|
|
cpar = pars_[pit];
|
|
|
|
if (cpar.params().depth() < current_depth)
|
|
|
|
res = cpar.layout().isEnvironment();
|
|
|
|
}
|
|
|
|
enable = res;
|
|
|
|
break;
|
|
|
|
}
|
2018-01-01 11:34:39 +00:00
|
|
|
else if (cmd.argument() == "previous") {
|
|
|
|
// look if we have an environment in the previous par
|
|
|
|
pit_type pit = cur.pit();
|
|
|
|
Paragraph cpar = pars_[pit];
|
|
|
|
if (pit > 0) {
|
|
|
|
--pit;
|
|
|
|
cpar = pars_[pit];
|
|
|
|
enable = cpar.layout().isEnvironment();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
enable = false;
|
|
|
|
break;
|
|
|
|
}
|
2014-01-27 07:01:24 +00:00
|
|
|
else if (cur.paragraph().layout().isEnvironment()) {
|
2018-01-03 12:16:07 +00:00
|
|
|
enable = cmd.argument() == "before"
|
|
|
|
|| cur.pos() > 0 || !isFirstInSequence(cur.pit());
|
2012-12-23 17:57:32 +00:00
|
|
|
break;
|
|
|
|
}
|
2012-12-24 10:22:23 +00:00
|
|
|
enable = false;
|
2012-12-23 17:57:32 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-02-08 11:19:48 +00:00
|
|
|
case LFUN_LAYOUT_PARAGRAPH:
|
|
|
|
case LFUN_PARAGRAPH_PARAMS:
|
|
|
|
case LFUN_PARAGRAPH_PARAMS_APPLY:
|
|
|
|
case LFUN_PARAGRAPH_UPDATE:
|
2016-05-12 15:31:47 +00:00
|
|
|
enable = owner_->allowParagraphCustomization();
|
2010-02-08 11:19:48 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
// FIXME: why are accent lfuns forbidden with pass_thru layouts?
|
2015-08-13 09:15:19 +00:00
|
|
|
// Because they insert COMBINING DIACRITICAL Unicode characters,
|
|
|
|
// that cannot be handled by LaTeX but must be converted according
|
|
|
|
// to the definition in lib/unicodesymbols?
|
2010-02-08 11:19:48 +00:00
|
|
|
case LFUN_ACCENT_ACUTE:
|
|
|
|
case LFUN_ACCENT_BREVE:
|
|
|
|
case LFUN_ACCENT_CARON:
|
|
|
|
case LFUN_ACCENT_CEDILLA:
|
|
|
|
case LFUN_ACCENT_CIRCLE:
|
|
|
|
case LFUN_ACCENT_CIRCUMFLEX:
|
|
|
|
case LFUN_ACCENT_DOT:
|
|
|
|
case LFUN_ACCENT_GRAVE:
|
|
|
|
case LFUN_ACCENT_HUNGARIAN_UMLAUT:
|
|
|
|
case LFUN_ACCENT_MACRON:
|
|
|
|
case LFUN_ACCENT_OGONEK:
|
|
|
|
case LFUN_ACCENT_TIE:
|
|
|
|
case LFUN_ACCENT_TILDE:
|
2015-08-13 09:15:19 +00:00
|
|
|
case LFUN_ACCENT_PERISPOMENI:
|
2010-02-08 11:19:48 +00:00
|
|
|
case LFUN_ACCENT_UMLAUT:
|
|
|
|
case LFUN_ACCENT_UNDERBAR:
|
|
|
|
case LFUN_ACCENT_UNDERDOT:
|
|
|
|
case LFUN_FONT_DEFAULT:
|
|
|
|
case LFUN_FONT_FRAK:
|
|
|
|
case LFUN_FONT_SIZE:
|
|
|
|
case LFUN_FONT_STATE:
|
|
|
|
case LFUN_FONT_UNDERLINE:
|
|
|
|
case LFUN_FONT_STRIKEOUT:
|
2017-04-04 22:01:19 +00:00
|
|
|
case LFUN_FONT_CROSSOUT:
|
2014-02-11 10:00:20 +00:00
|
|
|
case LFUN_FONT_UNDERUNDERLINE:
|
|
|
|
case LFUN_FONT_UNDERWAVE:
|
2010-02-08 11:19:48 +00:00
|
|
|
case LFUN_TEXTSTYLE_APPLY:
|
|
|
|
case LFUN_TEXTSTYLE_UPDATE:
|
2011-01-26 11:04:42 +00:00
|
|
|
enable = !cur.paragraph().isPassThru();
|
2010-02-08 11:19:48 +00:00
|
|
|
break;
|
|
|
|
|
2006-05-08 18:09:19 +00:00
|
|
|
case LFUN_WORD_DELETE_FORWARD:
|
|
|
|
case LFUN_WORD_DELETE_BACKWARD:
|
2014-02-11 10:00:20 +00:00
|
|
|
case LFUN_LINE_DELETE_FORWARD:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_WORD_FORWARD:
|
|
|
|
case LFUN_WORD_BACKWARD:
|
2007-10-28 20:35:57 +00:00
|
|
|
case LFUN_WORD_RIGHT:
|
|
|
|
case LFUN_WORD_LEFT:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_CHAR_FORWARD:
|
2006-05-08 18:09:19 +00:00
|
|
|
case LFUN_CHAR_FORWARD_SELECT:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_CHAR_BACKWARD:
|
2006-05-08 18:09:19 +00:00
|
|
|
case LFUN_CHAR_BACKWARD_SELECT:
|
2007-10-22 22:18:52 +00:00
|
|
|
case LFUN_CHAR_LEFT:
|
|
|
|
case LFUN_CHAR_LEFT_SELECT:
|
|
|
|
case LFUN_CHAR_RIGHT:
|
|
|
|
case LFUN_CHAR_RIGHT_SELECT:
|
2004-03-18 13:57:20 +00:00
|
|
|
case LFUN_UP:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_UP_SELECT:
|
2004-03-18 13:57:20 +00:00
|
|
|
case LFUN_DOWN:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_DOWN_SELECT:
|
2006-05-08 18:09:19 +00:00
|
|
|
case LFUN_PARAGRAPH_UP_SELECT:
|
|
|
|
case LFUN_PARAGRAPH_DOWN_SELECT:
|
|
|
|
case LFUN_LINE_BEGIN_SELECT:
|
|
|
|
case LFUN_LINE_END_SELECT:
|
|
|
|
case LFUN_WORD_FORWARD_SELECT:
|
|
|
|
case LFUN_WORD_BACKWARD_SELECT:
|
2007-10-28 20:35:57 +00:00
|
|
|
case LFUN_WORD_RIGHT_SELECT:
|
|
|
|
case LFUN_WORD_LEFT_SELECT:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_WORD_SELECT:
|
2009-05-03 18:58:00 +00:00
|
|
|
case LFUN_SECTION_SELECT:
|
2010-02-08 11:19:48 +00:00
|
|
|
case LFUN_BUFFER_BEGIN:
|
|
|
|
case LFUN_BUFFER_END:
|
|
|
|
case LFUN_BUFFER_BEGIN_SELECT:
|
|
|
|
case LFUN_BUFFER_END_SELECT:
|
|
|
|
case LFUN_INSET_BEGIN:
|
|
|
|
case LFUN_INSET_END:
|
|
|
|
case LFUN_INSET_BEGIN_SELECT:
|
|
|
|
case LFUN_INSET_END_SELECT:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_PARAGRAPH_UP:
|
|
|
|
case LFUN_PARAGRAPH_DOWN:
|
|
|
|
case LFUN_LINE_BEGIN:
|
|
|
|
case LFUN_LINE_END:
|
2006-05-08 18:09:19 +00:00
|
|
|
case LFUN_CHAR_DELETE_FORWARD:
|
|
|
|
case LFUN_CHAR_DELETE_BACKWARD:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_WORD_UPCASE:
|
|
|
|
case LFUN_WORD_LOWCASE:
|
|
|
|
case LFUN_WORD_CAPITALIZE:
|
|
|
|
case LFUN_CHARS_TRANSPOSE:
|
|
|
|
case LFUN_SERVER_GET_XY:
|
|
|
|
case LFUN_SERVER_SET_XY:
|
|
|
|
case LFUN_SERVER_GET_LAYOUT:
|
|
|
|
case LFUN_SELF_INSERT:
|
2010-02-08 11:19:48 +00:00
|
|
|
case LFUN_UNICODE_INSERT:
|
2004-03-18 13:57:20 +00:00
|
|
|
case LFUN_THESAURUS_ENTRY:
|
|
|
|
case LFUN_ESCAPE:
|
2014-10-14 19:55:04 +00:00
|
|
|
case LFUN_SERVER_GET_STATISTICS:
|
2004-11-30 01:59:49 +00:00
|
|
|
// these are handled in our dispatch()
|
2004-08-13 20:14:32 +00:00
|
|
|
enable = true;
|
|
|
|
break;
|
|
|
|
|
2010-09-12 07:56:08 +00:00
|
|
|
case LFUN_INSET_INSERT: {
|
|
|
|
string const type = cmd.getArg(0);
|
|
|
|
if (type == "toc") {
|
|
|
|
code = TOC_CODE;
|
|
|
|
// not allowed in description items
|
|
|
|
//FIXME: couldn't this be merged in Inset::insetAllowed()?
|
|
|
|
enable = !inDescriptionItem(cur);
|
|
|
|
} else {
|
|
|
|
enable = true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2004-03-18 13:57:20 +00:00
|
|
|
default:
|
2004-12-02 11:32:14 +00:00
|
|
|
return false;
|
2004-03-18 13:57:20 +00:00
|
|
|
}
|
2005-11-02 11:27:08 +00:00
|
|
|
|
2007-10-13 09:04:52 +00:00
|
|
|
if (code != NO_CODE
|
2014-03-14 13:22:26 +00:00
|
|
|
&& (cur.empty()
|
2009-07-14 21:56:22 +00:00
|
|
|
|| !cur.inset().insetAllowed(code)
|
2012-11-20 15:58:51 +00:00
|
|
|
|| (cur.paragraph().layout().pass_thru && !allow_in_passthru)))
|
2005-11-02 11:27:08 +00:00
|
|
|
enable = false;
|
|
|
|
|
2008-05-29 15:14:00 +00:00
|
|
|
flag.setEnabled(enable);
|
2004-03-18 13:57:20 +00:00
|
|
|
return true;
|
2002-08-20 13:00:25 +00:00
|
|
|
}
|
2006-10-21 00:16:43 +00:00
|
|
|
|
|
|
|
|
2007-04-29 23:33:02 +00:00
|
|
|
void Text::pasteString(Cursor & cur, docstring const & clip,
|
2007-01-06 15:33:07 +00:00
|
|
|
bool asParagraphs)
|
2007-01-03 07:30:50 +00:00
|
|
|
{
|
|
|
|
if (!clip.empty()) {
|
2007-10-18 11:51:17 +00:00
|
|
|
cur.recordUndo();
|
2007-01-06 15:33:07 +00:00
|
|
|
if (asParagraphs)
|
2009-08-09 16:49:41 +00:00
|
|
|
insertStringAsParagraphs(cur, clip, cur.current_font);
|
2007-01-03 07:30:50 +00:00
|
|
|
else
|
2009-08-09 16:49:41 +00:00
|
|
|
insertStringAsLines(cur, clip, cur.current_font);
|
2007-01-03 07:30:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-10-14 13:27:58 +00:00
|
|
|
|
|
|
|
// FIXME: an item inset would make things much easier.
|
|
|
|
bool Text::inDescriptionItem(Cursor & cur) const
|
|
|
|
{
|
|
|
|
Paragraph & par = cur.paragraph();
|
|
|
|
pos_type const pos = cur.pos();
|
|
|
|
pos_type const body_pos = par.beginOfBody();
|
|
|
|
|
|
|
|
if (par.layout().latextype != LATEX_LIST_ENVIRONMENT
|
|
|
|
&& (par.layout().latextype != LATEX_ITEM_ENVIRONMENT
|
|
|
|
|| par.layout().margintype != MARGIN_FIRST_DYNAMIC))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return (pos < body_pos
|
|
|
|
|| (pos == body_pos
|
|
|
|
&& (pos == 0 || par.getChar(pos - 1) != ' ')));
|
|
|
|
}
|
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
} // namespace lyx
|