2003-08-19 13:00:56 +00:00
|
|
|
/**
|
2007-04-25 03:01:35 +00:00
|
|
|
* \file InsetMathNest.cpp
|
2003-08-19 13:00:56 +00:00
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
* Licence details can be found in the file COPYING.
|
|
|
|
*
|
2008-11-14 15:58:50 +00:00
|
|
|
* \author André Pönitz
|
2003-08-19 13:00:56 +00:00
|
|
|
*
|
|
|
|
* Full author contact details are available in file CREDITS.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
2001-08-03 17:10:22 +00:00
|
|
|
|
2006-09-17 09:14:18 +00:00
|
|
|
#include "InsetMathNest.h"
|
2004-01-26 10:13:15 +00:00
|
|
|
|
2006-09-17 09:14:18 +00:00
|
|
|
#include "InsetMathArray.h"
|
2009-07-12 21:39:21 +00:00
|
|
|
#include "InsetMathAMSArray.h"
|
2006-09-17 09:14:18 +00:00
|
|
|
#include "InsetMathBig.h"
|
|
|
|
#include "InsetMathBox.h"
|
|
|
|
#include "InsetMathBrace.h"
|
2009-04-05 01:14:10 +00:00
|
|
|
#include "InsetMathChar.h"
|
2006-09-17 09:14:18 +00:00
|
|
|
#include "InsetMathColor.h"
|
|
|
|
#include "InsetMathComment.h"
|
|
|
|
#include "InsetMathDelim.h"
|
2009-05-20 14:52:03 +00:00
|
|
|
#include "InsetMathEnsureMath.h"
|
2006-09-17 09:14:18 +00:00
|
|
|
#include "InsetMathHull.h"
|
2007-04-29 16:22:46 +00:00
|
|
|
#include "InsetMathRef.h"
|
2006-09-17 09:14:18 +00:00
|
|
|
#include "InsetMathScript.h"
|
|
|
|
#include "InsetMathSpace.h"
|
|
|
|
#include "InsetMathSymbol.h"
|
|
|
|
#include "InsetMathUnknown.h"
|
2008-12-19 10:26:33 +00:00
|
|
|
#include "MathAutoCorrect.h"
|
2008-03-15 00:22:54 +00:00
|
|
|
#include "MathCompletionList.h"
|
2007-04-29 16:22:46 +00:00
|
|
|
#include "MathData.h"
|
|
|
|
#include "MathFactory.h"
|
2007-11-01 11:14:14 +00:00
|
|
|
#include "MathMacro.h"
|
2007-04-29 16:22:46 +00:00
|
|
|
#include "MathMacroArgument.h"
|
|
|
|
#include "MathParser.h"
|
|
|
|
#include "MathStream.h"
|
|
|
|
#include "MathSupport.h"
|
2004-01-30 11:41:12 +00:00
|
|
|
|
2007-09-20 20:44:08 +00:00
|
|
|
#include "Bidi.h"
|
2008-02-21 19:42:34 +00:00
|
|
|
#include "Buffer.h"
|
2015-01-19 20:37:01 +00:00
|
|
|
#include "BufferParams.h"
|
2002-08-22 07:06:02 +00:00
|
|
|
#include "BufferView.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
#include "CoordCache.h"
|
2007-04-26 14:56:30 +00:00
|
|
|
#include "Cursor.h"
|
2007-04-29 16:22:46 +00:00
|
|
|
#include "CutAndPaste.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
#include "DispatchResult.h"
|
2009-04-05 01:14:10 +00:00
|
|
|
#include "Encoding.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
#include "FuncRequest.h"
|
2007-04-29 16:22:46 +00:00
|
|
|
#include "FuncStatus.h"
|
2010-02-09 16:11:13 +00:00
|
|
|
#include "LyX.h"
|
2008-02-10 19:57:00 +00:00
|
|
|
#include "LyXRC.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
#include "OutputParams.h"
|
2008-02-18 07:14:42 +00:00
|
|
|
#include "Text.h"
|
2004-01-30 11:41:12 +00:00
|
|
|
|
2015-02-14 19:32:25 +00:00
|
|
|
#include "frontends/Application.h"
|
2007-01-04 12:05:24 +00:00
|
|
|
#include "frontends/Clipboard.h"
|
2002-06-14 10:48:27 +00:00
|
|
|
#include "frontends/Painter.h"
|
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
|
|
|
#include "frontends/Selection.h"
|
2001-08-03 17:10:22 +00:00
|
|
|
|
2008-04-30 08:26:40 +00:00
|
|
|
#include "support/lassert.h"
|
2008-02-18 07:14:42 +00:00
|
|
|
#include "support/debug.h"
|
|
|
|
#include "support/gettext.h"
|
|
|
|
#include "support/lstrings.h"
|
|
|
|
#include "support/textutils.h"
|
|
|
|
#include "support/docstream.h"
|
2006-09-29 22:06:28 +00:00
|
|
|
|
2008-02-21 19:42:34 +00:00
|
|
|
#include <algorithm>
|
2004-07-24 10:55:30 +00:00
|
|
|
#include <sstream>
|
|
|
|
|
2007-12-12 10:16:00 +00:00
|
|
|
using namespace std;
|
2007-12-12 19:57:42 +00:00
|
|
|
using namespace lyx::support;
|
2006-10-15 22:32:56 +00:00
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
namespace lyx {
|
|
|
|
|
|
|
|
using cap::copySelection;
|
|
|
|
using cap::grabAndEraseSelection;
|
|
|
|
using cap::cutSelection;
|
|
|
|
using cap::replaceSelection;
|
|
|
|
using cap::selClearOrDel;
|
2001-08-03 17:10:22 +00:00
|
|
|
|
2004-01-30 11:41:12 +00:00
|
|
|
|
2009-11-08 11:45:46 +00:00
|
|
|
InsetMathNest::InsetMathNest(Buffer * buf, idx_type nargs)
|
2010-04-30 14:47:46 +00:00
|
|
|
: InsetMath(buf), cells_(nargs), lock_(false)
|
2009-11-08 11:45:46 +00:00
|
|
|
{
|
|
|
|
setBuffer(*buf);
|
|
|
|
}
|
2001-08-03 17:10:22 +00:00
|
|
|
|
|
|
|
|
2007-05-31 12:30:17 +00:00
|
|
|
InsetMathNest::InsetMathNest(InsetMathNest const & inset)
|
2010-04-30 14:47:46 +00:00
|
|
|
: InsetMath(inset), cells_(inset.cells_), lock_(inset.lock_)
|
2007-05-31 12:30:17 +00:00
|
|
|
{}
|
|
|
|
|
|
|
|
|
2010-04-30 14:55:37 +00:00
|
|
|
InsetMathNest::~InsetMathNest()
|
|
|
|
{
|
|
|
|
map<BufferView const *, bool>::iterator it = mouse_hover_.begin();
|
|
|
|
map<BufferView const *, bool>::iterator end = mouse_hover_.end();
|
|
|
|
for (; it != end; ++it)
|
|
|
|
if (it->second)
|
|
|
|
it->first->clearLastInset(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-05-31 12:30:17 +00:00
|
|
|
InsetMathNest & InsetMathNest::operator=(InsetMathNest const & inset)
|
|
|
|
{
|
|
|
|
cells_ = inset.cells_;
|
|
|
|
lock_ = inset.lock_;
|
2010-04-30 14:47:46 +00:00
|
|
|
mouse_hover_.clear();
|
2007-05-31 12:30:17 +00:00
|
|
|
InsetMath::operator=(inset);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-08-03 10:30:34 +00:00
|
|
|
void InsetMathNest::setBuffer(Buffer & buffer)
|
|
|
|
{
|
|
|
|
InsetMath::setBuffer(buffer);
|
|
|
|
for (idx_type i = 0, n = nargs(); i != n; ++i) {
|
|
|
|
MathData & data = cell(i);
|
|
|
|
for (size_t j = 0; j != data.size(); ++j)
|
|
|
|
data[j].nucleus()->setBuffer(buffer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-16 18:11:38 +00:00
|
|
|
InsetMath::idx_type InsetMathNest::nargs() const
|
2001-08-03 17:10:22 +00:00
|
|
|
{
|
|
|
|
return cells_.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-10-17 16:23:27 +00:00
|
|
|
void InsetMathNest::cursorPos(BufferView const & bv,
|
|
|
|
CursorSlice const & sl, bool /*boundary*/,
|
|
|
|
int & x, int & y) const
|
2004-11-30 01:59:49 +00:00
|
|
|
{
|
|
|
|
// FIXME: This is a hack. Ideally, the coord cache should not store
|
|
|
|
// absolute positions, but relative ones. This would mean to call
|
2007-04-26 16:05:57 +00:00
|
|
|
// setXY() not in MathData::draw(), but in the parent insets' draw()
|
2004-11-30 01:59:49 +00:00
|
|
|
// with the correctly adjusted x,y values. But this means that we'd have
|
|
|
|
// to touch all (math)inset's draw() methods. Right now, we'll store
|
|
|
|
// absolute value, and make them here relative, only to make them
|
|
|
|
// absolute again when actually drawing the cursor. What a mess.
|
2013-04-25 21:27:10 +00:00
|
|
|
LASSERT(&sl.inset() == this, return);
|
2007-04-26 16:05:57 +00:00
|
|
|
MathData const & ar = sl.cell();
|
2006-10-17 16:23:27 +00:00
|
|
|
CoordCache const & coord_cache = bv.coordCache();
|
2006-10-13 16:44:44 +00:00
|
|
|
if (!coord_cache.getArrays().has(&ar)) {
|
2005-01-31 16:29:48 +00:00
|
|
|
// this can (semi-)legally happen if we just created this cell
|
2004-11-30 01:59:49 +00:00
|
|
|
// and it never has been drawn before. So don't ASSERT.
|
|
|
|
//lyxerr << "no cached data for array " << &ar << endl;
|
|
|
|
x = 0;
|
|
|
|
y = 0;
|
|
|
|
return;
|
|
|
|
}
|
2006-10-13 16:44:44 +00:00
|
|
|
Point const pt = coord_cache.getArrays().xy(&ar);
|
|
|
|
if (!coord_cache.getInsets().has(this)) {
|
2004-11-30 01:59:49 +00:00
|
|
|
// same as above
|
|
|
|
//lyxerr << "no cached data for inset " << this << endl;
|
|
|
|
x = 0;
|
|
|
|
y = 0;
|
|
|
|
return;
|
|
|
|
}
|
2006-10-13 16:44:44 +00:00
|
|
|
Point const pt2 = coord_cache.getInsets().xy(this);
|
2007-04-26 16:05:57 +00:00
|
|
|
//lyxerr << "retrieving position cache for MathData "
|
2007-12-12 19:28:07 +00:00
|
|
|
// << pt.x_ << ' ' << pt.y_ << endl;
|
2007-12-24 10:52:58 +00:00
|
|
|
x = pt.x_ - pt2.x_ + ar.pos2x(&bv, sl.pos());
|
2004-11-30 01:59:49 +00:00
|
|
|
y = pt.y_ - pt2.y_;
|
|
|
|
// lyxerr << "pt.y_ : " << pt.y_ << " pt2_.y_ : " << pt2.y_
|
|
|
|
// << " asc: " << ascent() << " des: " << descent()
|
|
|
|
// << " ar.asc: " << ar.ascent() << " ar.des: " << ar.descent() << endl;
|
2002-07-16 18:22:45 +00:00
|
|
|
// move cursor visually into empty cells ("blue rectangles");
|
2004-11-30 01:59:49 +00:00
|
|
|
if (ar.empty())
|
2002-07-16 18:22:45 +00:00
|
|
|
x += 2;
|
|
|
|
}
|
|
|
|
|
2005-04-04 22:11:53 +00:00
|
|
|
|
2006-09-16 18:11:38 +00:00
|
|
|
void InsetMathNest::metrics(MetricsInfo const & mi) const
|
2001-08-03 17:10:22 +00:00
|
|
|
{
|
2003-03-21 14:20:48 +00:00
|
|
|
MetricsInfo m = mi;
|
2007-09-24 13:52:04 +00:00
|
|
|
for (idx_type i = 0, n = nargs(); i != n; ++i) {
|
|
|
|
Dimension dim;
|
|
|
|
cell(i).metrics(m, dim);
|
|
|
|
}
|
2001-08-03 17:10:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-03-03 22:13:45 +00:00
|
|
|
void InsetMathNest::updateBuffer(ParIterator const & it, UpdateType utype)
|
2010-01-28 17:37:22 +00:00
|
|
|
{
|
|
|
|
for (idx_type i = 0, n = nargs(); i != n; ++i)
|
2010-03-03 22:13:45 +00:00
|
|
|
cell(i).updateBuffer(it, utype);
|
2010-01-28 17:37:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
bool InsetMathNest::idxNext(Cursor & cur) const
|
2001-08-03 17:10:22 +00:00
|
|
|
{
|
2013-04-25 21:27:10 +00:00
|
|
|
LASSERT(&cur.inset() == this, return false);
|
2004-02-03 14:29:00 +00:00
|
|
|
if (cur.idx() == cur.lastidx())
|
2001-08-03 17:10:22 +00:00
|
|
|
return false;
|
2004-01-15 17:34:44 +00:00
|
|
|
++cur.idx();
|
|
|
|
cur.pos() = 0;
|
2001-08-03 17:10:22 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-11-05 19:44:03 +00:00
|
|
|
bool InsetMathNest::idxForward(Cursor & cur) const
|
2001-08-03 17:10:22 +00:00
|
|
|
{
|
2004-01-16 12:36:23 +00:00
|
|
|
return idxNext(cur);
|
2001-08-03 17:10:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
bool InsetMathNest::idxPrev(Cursor & cur) const
|
2001-08-03 17:10:22 +00:00
|
|
|
{
|
2013-04-25 21:27:10 +00:00
|
|
|
LASSERT(&cur.inset() == this, return false);
|
2004-01-15 17:34:44 +00:00
|
|
|
if (cur.idx() == 0)
|
2001-08-03 17:10:22 +00:00
|
|
|
return false;
|
2004-01-15 17:34:44 +00:00
|
|
|
--cur.idx();
|
|
|
|
cur.pos() = cur.lastpos();
|
2001-08-03 17:10:22 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-11-05 19:44:03 +00:00
|
|
|
bool InsetMathNest::idxBackward(Cursor & cur) const
|
2001-08-03 17:10:22 +00:00
|
|
|
{
|
2004-01-16 12:36:23 +00:00
|
|
|
return idxPrev(cur);
|
2001-08-03 17:10:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
bool InsetMathNest::idxFirst(Cursor & cur) const
|
2001-08-03 17:10:22 +00:00
|
|
|
{
|
2013-04-25 21:27:10 +00:00
|
|
|
LASSERT(&cur.inset() == this, return false);
|
2001-08-03 17:10:22 +00:00
|
|
|
if (nargs() == 0)
|
|
|
|
return false;
|
2004-01-15 17:34:44 +00:00
|
|
|
cur.idx() = 0;
|
|
|
|
cur.pos() = 0;
|
2001-08-03 17:10:22 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
bool InsetMathNest::idxLast(Cursor & cur) const
|
2001-08-03 17:10:22 +00:00
|
|
|
{
|
2013-04-25 21:27:10 +00:00
|
|
|
LASSERT(&cur.inset() == this, return false);
|
2001-08-03 17:10:22 +00:00
|
|
|
if (nargs() == 0)
|
|
|
|
return false;
|
2004-02-03 14:29:00 +00:00
|
|
|
cur.idx() = cur.lastidx();
|
2004-01-15 17:34:44 +00:00
|
|
|
cur.pos() = cur.lastpos();
|
2001-08-03 17:10:22 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-16 18:11:38 +00:00
|
|
|
void InsetMathNest::dump() const
|
2001-08-03 17:10:22 +00:00
|
|
|
{
|
2006-10-21 00:16:43 +00:00
|
|
|
odocstringstream oss;
|
2006-10-19 16:51:30 +00:00
|
|
|
WriteStream os(oss);
|
2001-10-19 11:25:48 +00:00
|
|
|
os << "---------------------------------------------\n";
|
|
|
|
write(os);
|
|
|
|
os << "\n";
|
2004-11-30 01:59:49 +00:00
|
|
|
for (idx_type i = 0, n = nargs(); i != n; ++i)
|
2001-10-19 11:25:48 +00:00
|
|
|
os << cell(i) << "\n";
|
|
|
|
os << "---------------------------------------------\n";
|
2006-10-21 00:16:43 +00:00
|
|
|
lyxerr << to_utf8(oss.str());
|
2001-08-03 17:10:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-16 18:11:38 +00:00
|
|
|
void InsetMathNest::draw(PainterInfo & pi, int x, int y) const
|
2002-06-14 10:48:27 +00:00
|
|
|
{
|
2002-06-18 15:44:30 +00:00
|
|
|
#if 0
|
2002-06-14 12:24:28 +00:00
|
|
|
if (lock_)
|
2002-06-14 10:48:27 +00:00
|
|
|
pi.pain.fillRectangle(x, y - ascent(), width(), height(),
|
2007-10-25 12:41:02 +00:00
|
|
|
Color_mathlockbg);
|
2002-06-18 15:44:30 +00:00
|
|
|
#endif
|
2004-04-07 16:54:15 +00:00
|
|
|
setPosCache(pi, x, y);
|
2002-06-14 10:48:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-16 18:11:38 +00:00
|
|
|
void InsetMathNest::drawSelection(PainterInfo & pi, int x, int y) const
|
2002-07-26 17:23:44 +00:00
|
|
|
{
|
2006-10-13 16:44:44 +00:00
|
|
|
BufferView & bv = *pi.base.bv;
|
2004-02-02 17:32:56 +00:00
|
|
|
// this should use the x/y values given, not the cached values
|
2007-04-26 14:56:30 +00:00
|
|
|
Cursor & cur = bv.cursor();
|
2004-02-02 17:32:56 +00:00
|
|
|
if (!cur.selection())
|
|
|
|
return;
|
2007-11-01 22:17:22 +00:00
|
|
|
if (&cur.inset() != this)
|
2004-02-02 17:32:56 +00:00
|
|
|
return;
|
2004-11-30 01:59:49 +00:00
|
|
|
|
2006-01-27 22:24:37 +00:00
|
|
|
// FIXME: hack to get position cache warm
|
2007-11-06 14:07:49 +00:00
|
|
|
bool const original_drawing_state = pi.pain.isDrawingEnabled();
|
2006-10-30 10:09:59 +00:00
|
|
|
pi.pain.setDrawingEnabled(false);
|
|
|
|
draw(pi, x, y);
|
2007-11-06 14:07:49 +00:00
|
|
|
pi.pain.setDrawingEnabled(original_drawing_state);
|
2006-01-27 22:24:37 +00:00
|
|
|
|
2004-03-25 09:16:36 +00:00
|
|
|
CursorSlice s1 = cur.selBegin();
|
|
|
|
CursorSlice s2 = cur.selEnd();
|
2006-10-13 16:44:44 +00:00
|
|
|
|
2006-09-16 18:11:38 +00:00
|
|
|
//lyxerr << "InsetMathNest::drawing selection: "
|
2004-04-20 08:44:30 +00:00
|
|
|
// << " s1: " << s1 << " s2: " << s2 << endl;
|
2004-02-02 17:32:56 +00:00
|
|
|
if (s1.idx() == s2.idx()) {
|
2007-04-26 16:05:57 +00:00
|
|
|
MathData const & c = cell(s1.idx());
|
2007-09-24 13:52:04 +00:00
|
|
|
Geometry const & g = bv.coordCache().getArrays().geometry(&c);
|
2007-12-24 10:52:58 +00:00
|
|
|
int x1 = g.pos.x_ + c.pos2x(pi.base.bv, s1.pos());
|
2007-09-24 13:52:04 +00:00
|
|
|
int y1 = g.pos.y_ - g.dim.ascent();
|
2007-12-24 10:52:58 +00:00
|
|
|
int x2 = g.pos.x_ + c.pos2x(pi.base.bv, s2.pos());
|
2007-09-24 13:52:04 +00:00
|
|
|
int y2 = g.pos.y_ + g.dim.descent();
|
2007-10-25 12:41:02 +00:00
|
|
|
pi.pain.fillRectangle(x1, y1, x2 - x1, y2 - y1, Color_selection);
|
2006-09-16 18:11:38 +00:00
|
|
|
//lyxerr << "InsetMathNest::drawing selection 3: "
|
2004-04-18 07:34:15 +00:00
|
|
|
// << " x1: " << x1 << " x2: " << x2
|
2004-04-20 08:44:30 +00:00
|
|
|
// << " y1: " << y1 << " y2: " << y2 << endl;
|
2002-07-26 17:23:44 +00:00
|
|
|
} else {
|
2002-08-02 13:35:05 +00:00
|
|
|
for (idx_type i = 0; i < nargs(); ++i) {
|
2004-02-02 17:32:56 +00:00
|
|
|
if (idxBetween(i, s1.idx(), s2.idx())) {
|
2007-04-26 16:05:57 +00:00
|
|
|
MathData const & c = cell(i);
|
2007-09-24 13:52:04 +00:00
|
|
|
Geometry const & g = bv.coordCache().getArrays().geometry(&c);
|
|
|
|
int x1 = g.pos.x_;
|
|
|
|
int y1 = g.pos.y_ - g.dim.ascent();
|
|
|
|
int x2 = g.pos.x_ + g.dim.width();
|
|
|
|
int y2 = g.pos.y_ + g.dim.descent();
|
2007-10-25 12:41:02 +00:00
|
|
|
pi.pain.fillRectangle(x1, y1, x2 - x1, y2 - y1, Color_selection);
|
2002-08-02 13:35:05 +00:00
|
|
|
}
|
2002-07-26 17:23:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-16 18:11:38 +00:00
|
|
|
void InsetMathNest::validate(LaTeXFeatures & features) const
|
2001-08-03 17:10:22 +00:00
|
|
|
{
|
2001-09-26 16:52:34 +00:00
|
|
|
for (idx_type i = 0; i < nargs(); ++i)
|
2001-08-03 17:10:22 +00:00
|
|
|
cell(i).validate(features);
|
|
|
|
}
|
2001-10-24 09:16:06 +00:00
|
|
|
|
|
|
|
|
2006-09-16 18:11:38 +00:00
|
|
|
void InsetMathNest::replace(ReplaceData & rep)
|
2001-11-16 09:55:37 +00:00
|
|
|
{
|
|
|
|
for (idx_type i = 0; i < nargs(); ++i)
|
|
|
|
cell(i).replace(rep);
|
|
|
|
}
|
2002-02-01 17:01:30 +00:00
|
|
|
|
|
|
|
|
2007-04-26 16:05:57 +00:00
|
|
|
bool InsetMathNest::contains(MathData const & ar) const
|
2002-02-01 17:01:30 +00:00
|
|
|
{
|
|
|
|
for (idx_type i = 0; i < nargs(); ++i)
|
|
|
|
if (cell(i).contains(ar))
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
2002-02-11 15:55:13 +00:00
|
|
|
|
|
|
|
|
2006-09-16 18:11:38 +00:00
|
|
|
bool InsetMathNest::lock() const
|
2002-05-30 07:09:54 +00:00
|
|
|
{
|
|
|
|
return lock_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-16 18:11:38 +00:00
|
|
|
void InsetMathNest::lock(bool l)
|
2002-05-30 07:09:54 +00:00
|
|
|
{
|
|
|
|
lock_ = l;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-16 18:11:38 +00:00
|
|
|
bool InsetMathNest::isActive() const
|
2002-05-30 07:09:54 +00:00
|
|
|
{
|
2002-06-14 10:48:27 +00:00
|
|
|
return nargs() > 0;
|
2002-05-30 07:09:54 +00:00
|
|
|
}
|
2002-06-18 15:44:30 +00:00
|
|
|
|
|
|
|
|
2007-04-26 16:05:57 +00:00
|
|
|
MathData InsetMathNest::glue() const
|
2002-06-18 15:44:30 +00:00
|
|
|
{
|
2007-04-26 16:05:57 +00:00
|
|
|
MathData ar;
|
2004-01-20 14:25:24 +00:00
|
|
|
for (size_t i = 0; i < nargs(); ++i)
|
2002-07-30 13:56:02 +00:00
|
|
|
ar.append(cell(i));
|
2002-06-18 15:44:30 +00:00
|
|
|
return ar;
|
|
|
|
}
|
2002-06-27 18:12:50 +00:00
|
|
|
|
|
|
|
|
2006-09-16 18:11:38 +00:00
|
|
|
void InsetMathNest::write(WriteStream & os) const
|
2002-08-01 15:53:46 +00:00
|
|
|
{
|
2011-05-04 00:29:36 +00:00
|
|
|
MathEnsurer ensurer(os, currentMode() == MATH_MODE);
|
2009-07-03 00:05:58 +00:00
|
|
|
ModeSpecifier specifier(os, currentMode(), lockedMode());
|
2008-06-19 09:17:57 +00:00
|
|
|
docstring const latex_name = name();
|
2008-06-16 20:39:40 +00:00
|
|
|
os << '\\' << latex_name;
|
2004-01-20 14:25:24 +00:00
|
|
|
for (size_t i = 0; i < nargs(); ++i)
|
2002-08-01 15:53:46 +00:00
|
|
|
os << '{' << cell(i) << '}';
|
2002-08-02 14:29:42 +00:00
|
|
|
if (nargs() == 0)
|
2002-08-22 10:04:11 +00:00
|
|
|
os.pendingSpace(true);
|
|
|
|
if (lock_ && !os.latex()) {
|
|
|
|
os << "\\lyxlock";
|
|
|
|
os.pendingSpace(true);
|
|
|
|
}
|
2002-08-01 15:53:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-16 18:11:38 +00:00
|
|
|
void InsetMathNest::normalize(NormalStream & os) const
|
2002-08-01 15:53:46 +00:00
|
|
|
{
|
2008-06-19 09:17:57 +00:00
|
|
|
os << '[' << name();
|
2004-01-20 14:25:24 +00:00
|
|
|
for (size_t i = 0; i < nargs(); ++i)
|
2002-08-01 15:53:46 +00:00
|
|
|
os << ' ' << cell(i);
|
|
|
|
os << ']';
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-02-10 20:02:48 +00:00
|
|
|
void InsetMathNest::latex(otexstream & os, OutputParams const & runparams) const
|
2004-04-07 18:15:29 +00:00
|
|
|
{
|
Introduce a wrapper class for odocstream to help ensuring that no
blank lines may be inadvertently output. This is achieved by using two
special iomanip-like variables (breakln and safebreakln) in the lyx::
namespace. When they are inserted in the stream, a newline is output
only if not already at the beginning of a line. The difference between
breakln and safebreakln is that, if needed, the former outputs '\n'
and the latter "%\n".
In future, the new class will also be used for counting the number of
newlines issued. Even if the infractrure for doing that is already in
place, the counting is essentially still done the old way.
There are still places in the code where the functionality of the
class could be used, most probably. ATM, it is used for InsetTabular,
InsetListings, InsetFloat, and InsetText.
The Comment and GreyedOut insets required a special treatment and a
new InsetLayout parameter (Display) has been introduced. The default
for Display is "true", meaning that the corresponding latex
environment is of "display" type, i.e., it stands on its own, whereas
"false" means that the contents appear inline with the text. The
latter is the case for both Comment and GreyedOut insets.
Mostly, the only visible effects on latex exports should be the
disappearing of some redundant % chars and the appearing/disappearing
of null {} latex groups after a comment or lyxgreyedout environments
(they are related to the presence or absence of a space immediately
after those environments), as well as the fact that math environments
are now started on their own lines.
As a last thing, only the latex code between \begin{document} and
\end{document} goes through the new class, the preamble being directly
output through odocstream, as usual.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@37360 a592a061-630c-0410-9148-cb99ea01b6c8
2011-01-29 02:41:13 +00:00
|
|
|
WriteStream wi(os.os(), runparams.moving_arg, true,
|
2009-08-07 05:25:22 +00:00
|
|
|
runparams.dryrun ? WriteStream::wsDryrun : WriteStream::wsDefault,
|
|
|
|
runparams.encoding);
|
Introduce a wrapper class for odocstream to help ensuring that no
blank lines may be inadvertently output. This is achieved by using two
special iomanip-like variables (breakln and safebreakln) in the lyx::
namespace. When they are inserted in the stream, a newline is output
only if not already at the beginning of a line. The difference between
breakln and safebreakln is that, if needed, the former outputs '\n'
and the latter "%\n".
In future, the new class will also be used for counting the number of
newlines issued. Even if the infractrure for doing that is already in
place, the counting is essentially still done the old way.
There are still places in the code where the functionality of the
class could be used, most probably. ATM, it is used for InsetTabular,
InsetListings, InsetFloat, and InsetText.
The Comment and GreyedOut insets required a special treatment and a
new InsetLayout parameter (Display) has been introduced. The default
for Display is "true", meaning that the corresponding latex
environment is of "display" type, i.e., it stands on its own, whereas
"false" means that the contents appear inline with the text. The
latter is the case for both Comment and GreyedOut insets.
Mostly, the only visible effects on latex exports should be the
disappearing of some redundant % chars and the appearing/disappearing
of null {} latex groups after a comment or lyxgreyedout environments
(they are related to the presence or absence of a space immediately
after those environments), as well as the fact that math environments
are now started on their own lines.
As a last thing, only the latex code between \begin{document} and
\end{document} goes through the new class, the preamble being directly
output through odocstream, as usual.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@37360 a592a061-630c-0410-9148-cb99ea01b6c8
2011-01-29 02:41:13 +00:00
|
|
|
wi.canBreakLine(os.canBreakLine());
|
2004-04-07 18:15:29 +00:00
|
|
|
write(wi);
|
2014-05-20 19:52:29 +00:00
|
|
|
// Reset parbreak status after a math inset.
|
|
|
|
os.lastChar(0);
|
Introduce a wrapper class for odocstream to help ensuring that no
blank lines may be inadvertently output. This is achieved by using two
special iomanip-like variables (breakln and safebreakln) in the lyx::
namespace. When they are inserted in the stream, a newline is output
only if not already at the beginning of a line. The difference between
breakln and safebreakln is that, if needed, the former outputs '\n'
and the latter "%\n".
In future, the new class will also be used for counting the number of
newlines issued. Even if the infractrure for doing that is already in
place, the counting is essentially still done the old way.
There are still places in the code where the functionality of the
class could be used, most probably. ATM, it is used for InsetTabular,
InsetListings, InsetFloat, and InsetText.
The Comment and GreyedOut insets required a special treatment and a
new InsetLayout parameter (Display) has been introduced. The default
for Display is "true", meaning that the corresponding latex
environment is of "display" type, i.e., it stands on its own, whereas
"false" means that the contents appear inline with the text. The
latter is the case for both Comment and GreyedOut insets.
Mostly, the only visible effects on latex exports should be the
disappearing of some redundant % chars and the appearing/disappearing
of null {} latex groups after a comment or lyxgreyedout environments
(they are related to the presence or absence of a space immediately
after those environments), as well as the fact that math environments
are now started on their own lines.
As a last thing, only the latex code between \begin{document} and
\end{document} goes through the new class, the preamble being directly
output through odocstream, as usual.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@37360 a592a061-630c-0410-9148-cb99ea01b6c8
2011-01-29 02:41:13 +00:00
|
|
|
os.canBreakLine(wi.canBreakLine());
|
2011-03-12 01:40:01 +00:00
|
|
|
|
|
|
|
int lf = wi.line();
|
|
|
|
if (lf > 0 && runparams.lastid != -1) {
|
|
|
|
--lf;
|
|
|
|
os.texrow().newline();
|
|
|
|
os.texrow().start(runparams.lastid, runparams.lastpos);
|
|
|
|
}
|
|
|
|
os.texrow().newlines(lf);
|
2004-04-07 18:15:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-04-30 14:47:46 +00:00
|
|
|
bool InsetMathNest::setMouseHover(BufferView const * bv, bool mouse_hover)
|
2011-02-13 10:07:00 +00:00
|
|
|
const
|
2007-06-07 18:08:03 +00:00
|
|
|
{
|
2010-04-30 14:47:46 +00:00
|
|
|
mouse_hover_[bv] = mouse_hover;
|
2007-06-07 18:08:03 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-22 20:45:18 +00:00
|
|
|
bool InsetMathNest::notifyCursorLeaves(Cursor const & /*old*/, Cursor & /*cur*/)
|
2002-10-29 08:23:32 +00:00
|
|
|
{
|
2007-08-10 11:47:12 +00:00
|
|
|
// FIXME: look here
|
2004-04-08 15:03:33 +00:00
|
|
|
#if 0
|
2007-04-26 16:05:57 +00:00
|
|
|
MathData & ar = cur.cell();
|
2004-04-05 16:31:52 +00:00
|
|
|
// remove base-only "scripts"
|
2004-04-18 07:34:15 +00:00
|
|
|
for (pos_type i = 0; i + 1 < ar.size(); ++i) {
|
2006-09-16 18:11:38 +00:00
|
|
|
InsetMathScript * p = operator[](i).nucleus()->asScriptInset();
|
2004-04-08 15:03:33 +00:00
|
|
|
if (p && p->nargs() == 1) {
|
2007-04-26 16:05:57 +00:00
|
|
|
MathData ar = p->nuc();
|
2004-04-05 16:31:52 +00:00
|
|
|
erase(i);
|
|
|
|
insert(i, ar);
|
2004-04-08 15:03:33 +00:00
|
|
|
cur.adjust(i, ar.size() - 1);
|
2004-04-05 16:31:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// glue adjacent font insets of the same kind
|
|
|
|
for (pos_type i = 0; i + 1 < size(); ++i) {
|
2006-09-16 18:11:38 +00:00
|
|
|
InsetMathFont * p = operator[](i).nucleus()->asFontInset();
|
|
|
|
InsetMathFont const * q = operator[](i + 1)->asFontInset();
|
2004-04-05 16:31:52 +00:00
|
|
|
if (p && q && p->name() == q->name()) {
|
|
|
|
p->cell(0).append(q->cell(0));
|
|
|
|
erase(i + 1);
|
2004-04-08 15:03:33 +00:00
|
|
|
cur.adjust(i, -1);
|
2004-04-05 16:31:52 +00:00
|
|
|
}
|
|
|
|
}
|
2004-04-08 15:03:33 +00:00
|
|
|
#endif
|
2006-08-17 21:32:04 +00:00
|
|
|
return false;
|
2002-10-29 08:23:32 +00:00
|
|
|
}
|
2002-08-15 10:02:53 +00:00
|
|
|
|
|
|
|
|
2006-09-16 18:11:38 +00:00
|
|
|
void InsetMathNest::handleFont
|
2007-04-26 14:56:30 +00:00
|
|
|
(Cursor & cur, docstring const & arg, char const * const font)
|
2006-10-22 10:15:23 +00:00
|
|
|
{
|
|
|
|
handleFont(cur, arg, from_ascii(font));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-15 00:22:54 +00:00
|
|
|
void InsetMathNest::handleFont(Cursor & cur, docstring const & arg,
|
|
|
|
docstring const & font)
|
2004-01-30 11:41:12 +00:00
|
|
|
{
|
2008-03-18 10:58:57 +00:00
|
|
|
cur.recordUndoSelection();
|
|
|
|
|
2004-01-30 11:41:12 +00:00
|
|
|
// this whole function is a hack and won't work for incremental font
|
|
|
|
// changes...
|
2008-03-18 10:58:57 +00:00
|
|
|
if (cur.inset().asInsetMath()->name() == font)
|
2006-10-22 10:15:23 +00:00
|
|
|
cur.handleFont(to_utf8(font));
|
2008-03-18 10:58:57 +00:00
|
|
|
else
|
2009-11-08 11:45:46 +00:00
|
|
|
handleNest(cur, createInsetMath(font, cur.buffer()), arg);
|
2008-03-15 00:22:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void InsetMathNest::handleNest(Cursor & cur, MathAtom const & nest)
|
|
|
|
{
|
|
|
|
handleNest(cur, nest, docstring());
|
2008-03-12 14:04:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-15 00:22:54 +00:00
|
|
|
void InsetMathNest::handleNest(Cursor & cur, MathAtom const & nest,
|
|
|
|
docstring const & arg)
|
2008-03-12 14:04:25 +00:00
|
|
|
{
|
|
|
|
CursorSlice i1 = cur.selBegin();
|
|
|
|
CursorSlice i2 = cur.selEnd();
|
|
|
|
if (!i1.inset().asInsetMath())
|
|
|
|
return;
|
|
|
|
if (i1.idx() == i2.idx()) {
|
|
|
|
// the easy case where only one cell is selected
|
|
|
|
cur.handleNest(nest);
|
|
|
|
cur.insert(arg);
|
|
|
|
return;
|
|
|
|
}
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2008-03-12 14:04:25 +00:00
|
|
|
// multiple selected cells in a simple non-grid inset
|
|
|
|
if (i1.asInsetMath()->nrows() == 0 || i1.asInsetMath()->ncols() == 0) {
|
|
|
|
for (idx_type i = i1.idx(); i <= i2.idx(); ++i) {
|
|
|
|
// select cell
|
|
|
|
cur.idx() = i;
|
|
|
|
cur.pos() = 0;
|
|
|
|
cur.resetAnchor();
|
|
|
|
cur.pos() = cur.lastpos();
|
|
|
|
cur.setSelection();
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2008-03-12 14:04:25 +00:00
|
|
|
// change font of cell
|
|
|
|
cur.handleNest(nest);
|
2008-03-12 00:19:31 +00:00
|
|
|
cur.insert(arg);
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2008-03-12 14:04:25 +00:00
|
|
|
// cur is in the font inset now. If the loop continues,
|
|
|
|
// we need to get outside again for the next cell
|
|
|
|
if (i + 1 <= i2.idx())
|
|
|
|
cur.pop_back();
|
2008-03-12 00:19:31 +00:00
|
|
|
}
|
2008-03-12 14:04:25 +00:00
|
|
|
return;
|
|
|
|
}
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2008-03-12 14:04:25 +00:00
|
|
|
// the complicated case with multiple selected cells in a grid
|
2008-03-15 00:22:54 +00:00
|
|
|
row_type r1, r2;
|
|
|
|
col_type c1, c2;
|
2008-03-12 14:04:25 +00:00
|
|
|
cap::region(i1, i2, r1, r2, c1, c2);
|
2008-03-15 00:22:54 +00:00
|
|
|
for (row_type row = r1; row <= r2; ++row) {
|
|
|
|
for (col_type col = c1; col <= c2; ++col) {
|
2008-03-12 14:04:25 +00:00
|
|
|
// select cell
|
|
|
|
cur.idx() = i1.asInsetMath()->index(row, col);
|
|
|
|
cur.pos() = 0;
|
|
|
|
cur.resetAnchor();
|
|
|
|
cur.pos() = cur.lastpos();
|
|
|
|
cur.setSelection();
|
2008-10-13 11:25:37 +00:00
|
|
|
|
|
|
|
//
|
2008-03-12 14:04:25 +00:00
|
|
|
cur.handleNest(nest);
|
|
|
|
cur.insert(arg);
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2008-03-12 14:04:25 +00:00
|
|
|
// cur is in the font inset now. If the loop continues,
|
|
|
|
// we need to get outside again for the next cell
|
|
|
|
if (col + 1 <= c2 || row + 1 <= r2)
|
|
|
|
cur.pop_back();
|
2008-03-12 00:19:31 +00:00
|
|
|
}
|
2004-01-30 11:41:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
void InsetMathNest::handleFont2(Cursor & cur, docstring const & arg)
|
2004-01-30 11:41:12 +00:00
|
|
|
{
|
2008-03-18 10:58:57 +00:00
|
|
|
cur.recordUndoSelection();
|
2007-04-29 18:17:15 +00:00
|
|
|
Font font;
|
2004-01-30 11:41:12 +00:00
|
|
|
bool b;
|
2007-09-29 11:00:18 +00:00
|
|
|
font.fromString(to_utf8(arg), b);
|
2008-03-12 18:50:50 +00:00
|
|
|
if (font.fontInfo().color() != Color_inherit &&
|
|
|
|
font.fontInfo().color() != Color_ignore)
|
2009-11-08 11:45:46 +00:00
|
|
|
handleNest(cur, MathAtom(new InsetMathColor(buffer_, true, font.fontInfo().color())));
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2008-03-12 13:20:40 +00:00
|
|
|
// FIXME: support other font changes here as well?
|
2004-01-30 11:41:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
|
2002-08-15 10:02:53 +00:00
|
|
|
{
|
2010-01-28 17:37:22 +00:00
|
|
|
//LYXERR0("InsetMathNest: request: " << cmd);
|
2002-08-15 10:02:53 +00:00
|
|
|
|
2009-04-05 01:14:10 +00:00
|
|
|
Parse::flags parseflg = Parse::QUIET | Parse::USETEXT;
|
2008-10-17 21:40:11 +00:00
|
|
|
|
2010-04-09 19:00:42 +00:00
|
|
|
FuncCode const act = cmd.action();
|
|
|
|
switch (act) {
|
2002-08-15 10:02:53 +00:00
|
|
|
|
2008-10-17 21:40:11 +00:00
|
|
|
case LFUN_CLIPBOARD_PASTE:
|
|
|
|
parseflg |= Parse::VERBATIM;
|
|
|
|
// fall through
|
2004-01-20 14:25:24 +00:00
|
|
|
case LFUN_PASTE: {
|
2009-07-03 00:05:58 +00:00
|
|
|
if (cur.currentMode() <= TEXT_MODE)
|
2008-10-18 09:06:27 +00:00
|
|
|
parseflg |= Parse::TEXTMODE;
|
2008-03-12 00:59:29 +00:00
|
|
|
cur.recordUndoSelection();
|
2006-09-11 08:54:10 +00:00
|
|
|
cur.message(_("Paste"));
|
2004-04-18 07:34:15 +00:00
|
|
|
replaceSelection(cur);
|
2007-01-04 12:05:24 +00:00
|
|
|
docstring topaste;
|
|
|
|
if (cmd.argument().empty() && !theClipboard().isInternal())
|
2013-04-14 17:45:36 +00:00
|
|
|
topaste = theClipboard().getAsText(Clipboard::PlainTextType);
|
2007-01-04 12:05:24 +00:00
|
|
|
else {
|
|
|
|
size_t n = 0;
|
|
|
|
idocstringstream is(cmd.argument());
|
|
|
|
is >> n;
|
2015-01-19 20:37:01 +00:00
|
|
|
topaste = cap::selection(n, buffer().params().documentClassPtr());
|
2007-01-04 12:05:24 +00:00
|
|
|
}
|
2009-12-11 01:30:33 +00:00
|
|
|
cur.niceInsert(topaste, parseflg, false);
|
2004-04-18 07:34:15 +00:00
|
|
|
cur.clearSelection(); // bug 393
|
2010-07-09 14:37:00 +00:00
|
|
|
cur.forceBufferUpdate();
|
2007-10-18 11:51:17 +00:00
|
|
|
cur.finishUndo();
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2004-01-20 14:25:24 +00:00
|
|
|
}
|
2004-04-18 07:34:15 +00:00
|
|
|
|
|
|
|
case LFUN_CUT:
|
2007-10-18 11:51:17 +00:00
|
|
|
cur.recordUndo();
|
2004-04-18 07:34:15 +00:00
|
|
|
cutSelection(cur, true, true);
|
2006-09-11 08:54:10 +00:00
|
|
|
cur.message(_("Cut"));
|
2005-09-19 09:57:04 +00:00
|
|
|
// Prevent stale position >= size crash
|
2005-10-12 18:44:53 +00:00
|
|
|
// Probably not necessary anymore, see eraseSelection (gb 2005-10-09)
|
2005-09-19 09:57:04 +00:00
|
|
|
cur.normalize();
|
2010-07-09 14:37:00 +00:00
|
|
|
cur.forceBufferUpdate();
|
2004-04-18 07:34:15 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case LFUN_COPY:
|
|
|
|
copySelection(cur);
|
2006-09-11 08:54:10 +00:00
|
|
|
cur.message(_("Copy"));
|
2004-04-18 07:34:15 +00:00
|
|
|
break;
|
2002-12-01 22:59:25 +00:00
|
|
|
|
2004-01-20 14:25:24 +00:00
|
|
|
case LFUN_MOUSE_PRESS:
|
2004-02-16 11:58:51 +00:00
|
|
|
lfunMousePress(cur, cmd);
|
|
|
|
break;
|
|
|
|
|
2004-02-06 16:14:06 +00:00
|
|
|
case LFUN_MOUSE_MOTION:
|
2004-02-16 11:58:51 +00:00
|
|
|
lfunMouseMotion(cur, cmd);
|
|
|
|
break;
|
|
|
|
|
2004-02-06 16:14:06 +00:00
|
|
|
case LFUN_MOUSE_RELEASE:
|
2004-02-16 11:58:51 +00:00
|
|
|
lfunMouseRelease(cur, cmd);
|
|
|
|
break;
|
|
|
|
|
2008-02-10 19:57:00 +00:00
|
|
|
case LFUN_FINISHED_LEFT: // in math, left is backwards
|
2007-10-22 22:18:52 +00:00
|
|
|
case LFUN_FINISHED_BACKWARD:
|
2004-02-16 11:58:51 +00:00
|
|
|
cur.bv().cursor() = cur;
|
|
|
|
break;
|
|
|
|
|
2008-02-10 19:57:00 +00:00
|
|
|
case LFUN_FINISHED_RIGHT: // in math, right is forward
|
2007-10-22 22:18:52 +00:00
|
|
|
case LFUN_FINISHED_FORWARD:
|
2004-02-16 11:58:51 +00:00
|
|
|
++cur.pos();
|
|
|
|
cur.bv().cursor() = cur;
|
|
|
|
break;
|
|
|
|
|
2008-02-10 19:57:00 +00:00
|
|
|
case LFUN_CHAR_RIGHT:
|
|
|
|
case LFUN_CHAR_LEFT:
|
|
|
|
case LFUN_CHAR_BACKWARD:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_CHAR_FORWARD:
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.screenUpdateFlags(Update::Decoration | Update::FitCursor);
|
2008-02-10 19:57:00 +00:00
|
|
|
case LFUN_CHAR_RIGHT_SELECT:
|
|
|
|
case LFUN_CHAR_LEFT_SELECT:
|
|
|
|
case LFUN_CHAR_BACKWARD_SELECT:
|
|
|
|
case LFUN_CHAR_FORWARD_SELECT: {
|
|
|
|
// are we in a selection?
|
2010-04-09 19:00:42 +00:00
|
|
|
bool select = (act == LFUN_CHAR_RIGHT_SELECT
|
|
|
|
|| act == LFUN_CHAR_LEFT_SELECT
|
|
|
|
|| act == LFUN_CHAR_BACKWARD_SELECT
|
|
|
|
|| act == LFUN_CHAR_FORWARD_SELECT);
|
2008-10-13 11:25:37 +00:00
|
|
|
// are we moving forward or backwards?
|
2008-02-10 19:57:00 +00:00
|
|
|
// If the command was RIGHT or LEFT, then whether we're moving forward
|
|
|
|
// or backwards depends on the cursor movement mode (logical or visual):
|
2008-10-13 11:25:37 +00:00
|
|
|
// * in visual mode, since math is always LTR, right -> forward,
|
2008-02-10 19:57:00 +00:00
|
|
|
// left -> backwards
|
|
|
|
// * in logical mode, the mapping is determined by the
|
|
|
|
// reverseDirectionNeeded() function
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2008-02-10 19:57:00 +00:00
|
|
|
bool forward;
|
2008-03-15 01:20:36 +00:00
|
|
|
FuncCode finish_lfun;
|
2008-02-10 19:57:00 +00:00
|
|
|
|
2010-04-09 19:00:42 +00:00
|
|
|
if (act == LFUN_CHAR_FORWARD
|
|
|
|
|| act == LFUN_CHAR_FORWARD_SELECT) {
|
2008-02-10 19:57:00 +00:00
|
|
|
forward = true;
|
|
|
|
finish_lfun = LFUN_FINISHED_FORWARD;
|
|
|
|
}
|
2010-04-09 19:00:42 +00:00
|
|
|
else if (act == LFUN_CHAR_BACKWARD
|
|
|
|
|| act == LFUN_CHAR_BACKWARD_SELECT) {
|
2008-02-10 19:57:00 +00:00
|
|
|
forward = false;
|
|
|
|
finish_lfun = LFUN_FINISHED_BACKWARD;
|
|
|
|
}
|
2005-07-18 00:09:20 +00:00
|
|
|
else {
|
2010-04-09 19:00:42 +00:00
|
|
|
bool right = (act == LFUN_CHAR_RIGHT_SELECT
|
|
|
|
|| act == LFUN_CHAR_RIGHT);
|
2008-02-10 19:57:00 +00:00
|
|
|
if (lyxrc.visual_cursor || !reverseDirectionNeeded(cur))
|
|
|
|
forward = right;
|
2008-10-13 11:25:37 +00:00
|
|
|
else
|
2008-02-10 19:57:00 +00:00
|
|
|
forward = !right;
|
|
|
|
|
|
|
|
if (right)
|
|
|
|
finish_lfun = LFUN_FINISHED_RIGHT;
|
|
|
|
else
|
|
|
|
finish_lfun = LFUN_FINISHED_LEFT;
|
2005-07-18 00:09:20 +00:00
|
|
|
}
|
2008-02-10 19:57:00 +00:00
|
|
|
// Now that we know exactly what we want to do, let's do it!
|
|
|
|
cur.selHandle(select);
|
2004-02-25 14:39:14 +00:00
|
|
|
cur.clearTargetX();
|
2004-08-13 09:31:48 +00:00
|
|
|
cur.macroModeClose();
|
2008-02-10 19:57:00 +00:00
|
|
|
// try moving forward or backwards as necessary...
|
|
|
|
if (!(forward ? cursorMathForward(cur) : cursorMathBackward(cur))) {
|
|
|
|
// ... and if movement failed, then finish forward or backwards
|
|
|
|
// as necessary
|
|
|
|
cmd = FuncRequest(finish_lfun);
|
2005-07-18 00:09:20 +00:00
|
|
|
cur.undispatched();
|
|
|
|
}
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2008-02-10 19:57:00 +00:00
|
|
|
}
|
2007-10-22 22:18:52 +00:00
|
|
|
|
2004-01-20 14:25:24 +00:00
|
|
|
case LFUN_DOWN:
|
2007-06-14 20:32:28 +00:00
|
|
|
case LFUN_UP:
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.screenUpdateFlags(Update::Decoration | Update::FitCursor);
|
2007-08-11 08:48:57 +00:00
|
|
|
case LFUN_DOWN_SELECT:
|
2007-06-14 20:32:28 +00:00
|
|
|
case LFUN_UP_SELECT: {
|
|
|
|
// close active macro
|
2005-04-08 12:15:28 +00:00
|
|
|
if (cur.inMacroMode()) {
|
|
|
|
cur.macroModeClose();
|
|
|
|
break;
|
|
|
|
}
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2007-06-14 20:32:28 +00:00
|
|
|
// stop/start the selection
|
2010-04-09 19:00:42 +00:00
|
|
|
bool select = act == LFUN_DOWN_SELECT ||
|
|
|
|
act == LFUN_UP_SELECT;
|
2007-06-14 20:32:28 +00:00
|
|
|
cur.selHandle(select);
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2013-02-10 05:51:30 +00:00
|
|
|
// handle autocorrect:
|
|
|
|
cur.autocorrect() = false;
|
|
|
|
cur.message(_("Autocorrect Off ('!' to enter)"));
|
|
|
|
|
2007-06-14 20:32:28 +00:00
|
|
|
// go up/down
|
2010-04-09 19:00:42 +00:00
|
|
|
bool up = act == LFUN_UP || act == LFUN_UP_SELECT;
|
2007-06-14 20:32:28 +00:00
|
|
|
bool successful = cur.upDownInMath(up);
|
2008-02-22 20:45:18 +00:00
|
|
|
if (successful)
|
2007-08-19 13:32:21 +00:00
|
|
|
break;
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2007-08-19 13:32:21 +00:00
|
|
|
if (cur.fixIfBroken())
|
|
|
|
// FIXME: Something bad happened. We pass the corrected Cursor
|
|
|
|
// instead of letting things go worse.
|
|
|
|
break;
|
|
|
|
|
|
|
|
// We did not manage to move the cursor.
|
|
|
|
cur.undispatched();
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2007-06-14 20:32:28 +00:00
|
|
|
}
|
2004-01-20 14:25:24 +00:00
|
|
|
|
2004-03-18 12:53:43 +00:00
|
|
|
case LFUN_MOUSE_DOUBLE:
|
|
|
|
case LFUN_MOUSE_TRIPLE:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_WORD_SELECT:
|
2004-02-25 14:39:14 +00:00
|
|
|
cur.pos() = 0;
|
|
|
|
cur.idx() = 0;
|
2004-02-11 14:45:44 +00:00
|
|
|
cur.resetAnchor();
|
2008-09-24 21:27:41 +00:00
|
|
|
cur.setSelection(true);
|
2004-02-25 14:39:14 +00:00
|
|
|
cur.idx() = cur.lastidx();
|
2014-04-04 09:39:22 +00:00
|
|
|
cur.pos() = cur.lastpos();
|
2014-03-21 09:20:12 +00:00
|
|
|
cur.bv().cursor() = cur;
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2004-01-26 10:13:15 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_PARAGRAPH_UP:
|
|
|
|
case LFUN_PARAGRAPH_DOWN:
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.screenUpdateFlags(Update::Decoration | Update::FitCursor);
|
2006-11-21 16:58:45 +00:00
|
|
|
case LFUN_PARAGRAPH_UP_SELECT:
|
|
|
|
case LFUN_PARAGRAPH_DOWN_SELECT:
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2004-01-26 10:13:15 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_LINE_BEGIN:
|
|
|
|
case LFUN_WORD_BACKWARD:
|
2007-10-28 20:35:57 +00:00
|
|
|
case LFUN_WORD_LEFT:
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.screenUpdateFlags(Update::Decoration | Update::FitCursor);
|
2006-11-21 16:58:45 +00:00
|
|
|
case LFUN_LINE_BEGIN_SELECT:
|
|
|
|
case LFUN_WORD_BACKWARD_SELECT:
|
2007-10-28 20:35:57 +00:00
|
|
|
case LFUN_WORD_LEFT_SELECT:
|
2010-04-09 19:00:42 +00:00
|
|
|
cur.selHandle(act == LFUN_WORD_BACKWARD_SELECT ||
|
|
|
|
act == LFUN_WORD_LEFT_SELECT ||
|
|
|
|
act == LFUN_LINE_BEGIN_SELECT);
|
2004-02-25 14:39:14 +00:00
|
|
|
cur.macroModeClose();
|
|
|
|
if (cur.pos() != 0) {
|
|
|
|
cur.pos() = 0;
|
|
|
|
} else if (cur.col() != 0) {
|
|
|
|
cur.idx() -= cur.col();
|
|
|
|
cur.pos() = 0;
|
|
|
|
} else if (cur.idx() != 0) {
|
|
|
|
cur.idx() = 0;
|
|
|
|
cur.pos() = 0;
|
|
|
|
} else {
|
2007-10-22 22:18:52 +00:00
|
|
|
cmd = FuncRequest(LFUN_FINISHED_BACKWARD);
|
2005-04-10 09:07:28 +00:00
|
|
|
cur.undispatched();
|
2004-02-25 14:39:14 +00:00
|
|
|
}
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2004-01-26 10:13:15 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_WORD_FORWARD:
|
2007-10-28 20:35:57 +00:00
|
|
|
case LFUN_WORD_RIGHT:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_LINE_END:
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.screenUpdateFlags(Update::Decoration | Update::FitCursor);
|
2006-11-21 16:58:45 +00:00
|
|
|
case LFUN_WORD_FORWARD_SELECT:
|
2007-10-28 20:35:57 +00:00
|
|
|
case LFUN_WORD_RIGHT_SELECT:
|
2006-11-21 16:58:45 +00:00
|
|
|
case LFUN_LINE_END_SELECT:
|
2010-04-09 19:00:42 +00:00
|
|
|
cur.selHandle(act == LFUN_WORD_FORWARD_SELECT ||
|
|
|
|
act == LFUN_WORD_RIGHT_SELECT ||
|
|
|
|
act == LFUN_LINE_END_SELECT);
|
2004-02-25 14:39:14 +00:00
|
|
|
cur.macroModeClose();
|
|
|
|
cur.clearTargetX();
|
|
|
|
if (cur.pos() != cur.lastpos()) {
|
|
|
|
cur.pos() = cur.lastpos();
|
2005-04-06 19:01:55 +00:00
|
|
|
} else if (ncols() && (cur.col() != cur.lastcol())) {
|
2004-02-25 14:39:14 +00:00
|
|
|
cur.idx() = cur.idx() - cur.col() + cur.lastcol();
|
|
|
|
cur.pos() = cur.lastpos();
|
|
|
|
} else if (cur.idx() != cur.lastidx()) {
|
|
|
|
cur.idx() = cur.lastidx();
|
|
|
|
cur.pos() = cur.lastpos();
|
|
|
|
} else {
|
2007-10-22 22:18:52 +00:00
|
|
|
cmd = FuncRequest(LFUN_FINISHED_FORWARD);
|
2005-04-10 09:07:28 +00:00
|
|
|
cur.undispatched();
|
2004-02-25 14:39:14 +00:00
|
|
|
}
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2004-01-26 10:13:15 +00:00
|
|
|
|
|
|
|
case LFUN_CELL_FORWARD:
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.screenUpdateFlags(Update::Decoration | Update::FitCursor);
|
2004-03-18 12:53:43 +00:00
|
|
|
cur.inset().idxNext(cur);
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2004-01-26 10:13:15 +00:00
|
|
|
|
|
|
|
case LFUN_CELL_BACKWARD:
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.screenUpdateFlags(Update::Decoration | Update::FitCursor);
|
2004-03-18 12:53:43 +00:00
|
|
|
cur.inset().idxPrev(cur);
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2004-01-26 10:13:15 +00:00
|
|
|
|
2006-05-08 18:09:19 +00:00
|
|
|
case LFUN_WORD_DELETE_BACKWARD:
|
|
|
|
case LFUN_CHAR_DELETE_BACKWARD:
|
2005-10-03 09:50:28 +00:00
|
|
|
if (cur.pos() == 0)
|
2006-04-13 08:40:11 +00:00
|
|
|
// May affect external cell:
|
2007-10-18 11:51:17 +00:00
|
|
|
cur.recordUndoInset();
|
2012-04-17 08:55:59 +00:00
|
|
|
else if (!cur.inMacroMode())
|
2008-03-12 00:59:29 +00:00
|
|
|
cur.recordUndoSelection();
|
2006-11-19 18:33:13 +00:00
|
|
|
// if the inset can not be removed from within, delete it
|
|
|
|
if (!cur.backspace()) {
|
|
|
|
FuncRequest cmd = FuncRequest(LFUN_CHAR_DELETE_FORWARD);
|
2007-02-01 20:05:59 +00:00
|
|
|
cur.innerText()->dispatch(cur, cmd);
|
2006-11-19 18:33:13 +00:00
|
|
|
}
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2004-01-26 10:13:15 +00:00
|
|
|
|
2006-05-08 18:09:19 +00:00
|
|
|
case LFUN_WORD_DELETE_FORWARD:
|
|
|
|
case LFUN_CHAR_DELETE_FORWARD:
|
2006-04-13 08:40:11 +00:00
|
|
|
if (cur.pos() == cur.lastpos())
|
|
|
|
// May affect external cell:
|
2007-10-18 11:51:17 +00:00
|
|
|
cur.recordUndoInset();
|
2006-04-13 08:40:11 +00:00
|
|
|
else
|
2008-03-12 00:59:29 +00:00
|
|
|
cur.recordUndoSelection();
|
2006-11-19 18:33:13 +00:00
|
|
|
// if the inset can not be removed from within, delete it
|
|
|
|
if (!cur.erase()) {
|
|
|
|
FuncRequest cmd = FuncRequest(LFUN_CHAR_DELETE_FORWARD);
|
2007-02-01 20:05:59 +00:00
|
|
|
cur.innerText()->dispatch(cur, cmd);
|
2006-11-19 18:33:13 +00:00
|
|
|
}
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2004-01-26 10:13:15 +00:00
|
|
|
|
|
|
|
case LFUN_ESCAPE:
|
2004-04-03 08:37:12 +00:00
|
|
|
if (cur.selection())
|
2004-04-07 08:07:26 +00:00
|
|
|
cur.clearSelection();
|
2005-07-14 14:48:46 +00:00
|
|
|
else {
|
2007-10-22 22:18:52 +00:00
|
|
|
cmd = FuncRequest(LFUN_FINISHED_FORWARD);
|
2005-07-14 14:48:46 +00:00
|
|
|
cur.undispatched();
|
|
|
|
}
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2004-01-26 10:13:15 +00:00
|
|
|
|
2007-12-10 19:50:12 +00:00
|
|
|
// 'Locks' the math inset. A 'locked' math inset behaves as a unit
|
|
|
|
// that is traversed by a single <CursorLeft>/<CursorRight>.
|
2004-01-26 10:13:15 +00:00
|
|
|
case LFUN_INSET_TOGGLE:
|
2007-10-18 11:51:17 +00:00
|
|
|
cur.recordUndo();
|
2006-08-11 21:41:56 +00:00
|
|
|
lock(!lock());
|
2007-11-05 19:41:16 +00:00
|
|
|
cur.popForward();
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2004-01-26 10:13:15 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_SELF_INSERT:
|
2006-09-01 15:41:38 +00:00
|
|
|
if (cmd.argument().size() != 1) {
|
2008-03-12 00:59:29 +00:00
|
|
|
cur.recordUndoSelection();
|
2006-10-22 10:15:23 +00:00
|
|
|
docstring const arg = cmd.argument();
|
2006-10-19 16:38:13 +00:00
|
|
|
if (!interpretString(cur, arg))
|
2006-09-01 15:41:38 +00:00
|
|
|
cur.insert(arg);
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2004-01-26 10:13:15 +00:00
|
|
|
}
|
2009-07-09 18:00:27 +00:00
|
|
|
// Don't record undo steps if we are in macro mode and thus
|
2005-10-12 18:40:22 +00:00
|
|
|
// cmd.argument is the next character of the macro name.
|
|
|
|
// Otherwise we'll get an invalid cursor if we undo after
|
|
|
|
// the macro was finished and the macro is a known command,
|
2007-04-26 14:56:30 +00:00
|
|
|
// e.g. sqrt. Cursor::macroModeClose replaces in this case
|
2006-09-16 18:11:38 +00:00
|
|
|
// the InsetMathUnknown with name "frac" by an empty
|
|
|
|
// InsetMathFrac -> a pos value > 0 is invalid.
|
2005-10-12 18:40:22 +00:00
|
|
|
// A side effect is that an undo before the macro is finished
|
|
|
|
// undoes the complete macro, not only the last character.
|
2009-07-09 18:00:27 +00:00
|
|
|
// At the time we hit '\' we are not in macro mode, still.
|
|
|
|
if (!cur.inMacroMode())
|
|
|
|
cur.recordUndoSelection();
|
2006-01-11 17:08:50 +00:00
|
|
|
|
|
|
|
// spacial handling of space. If we insert an inset
|
|
|
|
// via macro mode, we want to put the cursor inside it
|
|
|
|
// if relevant. Think typing "\frac<space>".
|
2006-09-01 15:41:38 +00:00
|
|
|
if (cmd.argument()[0] == ' '
|
2006-01-11 17:08:50 +00:00
|
|
|
&& cur.inMacroMode() && cur.macroName() != "\\"
|
2012-03-25 09:16:32 +00:00
|
|
|
&& cur.macroModeClose() && cur.pos() > 0) {
|
2006-01-11 17:08:50 +00:00
|
|
|
MathAtom const atom = cur.prevAtom();
|
2007-06-11 18:26:42 +00:00
|
|
|
if (atom->asNestInset() && atom->isActive()) {
|
2007-11-05 19:41:16 +00:00
|
|
|
cur.posBackward();
|
|
|
|
cur.pushBackward(*cur.nextInset());
|
2006-01-11 17:08:50 +00:00
|
|
|
}
|
2006-10-19 18:56:16 +00:00
|
|
|
} else if (!interpretChar(cur, cmd.argument()[0])) {
|
2007-10-22 22:18:52 +00:00
|
|
|
cmd = FuncRequest(LFUN_FINISHED_FORWARD);
|
2006-10-19 18:56:16 +00:00
|
|
|
cur.undispatched();
|
2005-07-18 00:09:20 +00:00
|
|
|
}
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2004-01-26 10:13:15 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
//case LFUN_SERVER_GET_XY:
|
2004-04-18 19:41:40 +00:00
|
|
|
// break;
|
2004-01-26 10:13:15 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_SERVER_SET_XY: {
|
|
|
|
lyxerr << "LFUN_SERVER_SET_XY broken!" << endl;
|
2004-01-26 10:13:15 +00:00
|
|
|
int x = 0;
|
|
|
|
int y = 0;
|
2006-10-21 00:16:43 +00:00
|
|
|
istringstream is(to_utf8(cmd.argument()));
|
2004-01-26 10:13:15 +00:00
|
|
|
is >> x >> y;
|
|
|
|
cur.setScreenPos(x, y);
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2004-01-26 10:13:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Special casing for superscript in case of LyX handling
|
|
|
|
// dead-keys:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_ACCENT_CIRCUMFLEX:
|
2006-09-01 15:41:38 +00:00
|
|
|
if (cmd.argument().empty()) {
|
2004-01-26 10:13:15 +00:00
|
|
|
// do superscript if LyX handles
|
|
|
|
// deadkeys
|
2008-03-12 00:59:29 +00:00
|
|
|
cur.recordUndoSelection();
|
2006-03-20 14:42:04 +00:00
|
|
|
script(cur, true, grabAndEraseSelection(cur));
|
2004-01-26 10:13:15 +00:00
|
|
|
}
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2004-01-26 10:13:15 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_ACCENT_UMLAUT:
|
|
|
|
case LFUN_ACCENT_ACUTE:
|
|
|
|
case LFUN_ACCENT_GRAVE:
|
|
|
|
case LFUN_ACCENT_BREVE:
|
|
|
|
case LFUN_ACCENT_DOT:
|
|
|
|
case LFUN_ACCENT_MACRON:
|
|
|
|
case LFUN_ACCENT_CARON:
|
|
|
|
case LFUN_ACCENT_TILDE:
|
|
|
|
case LFUN_ACCENT_CEDILLA:
|
|
|
|
case LFUN_ACCENT_CIRCLE:
|
|
|
|
case LFUN_ACCENT_UNDERDOT:
|
|
|
|
case LFUN_ACCENT_TIE:
|
|
|
|
case LFUN_ACCENT_OGONEK:
|
|
|
|
case LFUN_ACCENT_HUNGARIAN_UMLAUT:
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2004-01-26 10:13:15 +00:00
|
|
|
|
|
|
|
// Math fonts
|
2008-06-11 08:35:15 +00:00
|
|
|
case LFUN_TEXTSTYLE_APPLY:
|
|
|
|
case LFUN_TEXTSTYLE_UPDATE:
|
2006-10-22 10:15:23 +00:00
|
|
|
handleFont2(cur, cmd.argument());
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2004-01-26 10:13:15 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_BOLD:
|
2009-07-03 00:05:58 +00:00
|
|
|
if (currentMode() <= TEXT_MODE)
|
2008-09-15 16:49:11 +00:00
|
|
|
handleFont(cur, cmd.argument(), "textbf");
|
|
|
|
else
|
|
|
|
handleFont(cur, cmd.argument(), "mathbf");
|
|
|
|
break;
|
|
|
|
case LFUN_FONT_BOLDSYMBOL:
|
2009-07-03 00:05:58 +00:00
|
|
|
if (currentMode() <= TEXT_MODE)
|
2006-10-22 10:15:23 +00:00
|
|
|
handleFont(cur, cmd.argument(), "textbf");
|
2005-06-24 10:14:33 +00:00
|
|
|
else
|
2008-03-09 23:23:50 +00:00
|
|
|
handleFont(cur, cmd.argument(), "boldsymbol");
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_SANS:
|
2009-07-03 00:05:58 +00:00
|
|
|
if (currentMode() <= TEXT_MODE)
|
2006-10-22 10:15:23 +00:00
|
|
|
handleFont(cur, cmd.argument(), "textsf");
|
2005-06-24 10:14:33 +00:00
|
|
|
else
|
2006-10-22 10:15:23 +00:00
|
|
|
handleFont(cur, cmd.argument(), "mathsf");
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_EMPH:
|
2009-07-03 00:05:58 +00:00
|
|
|
if (currentMode() <= TEXT_MODE)
|
2006-10-22 10:15:23 +00:00
|
|
|
handleFont(cur, cmd.argument(), "emph");
|
2005-06-24 10:14:33 +00:00
|
|
|
else
|
2006-10-22 10:15:23 +00:00
|
|
|
handleFont(cur, cmd.argument(), "mathcal");
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_ROMAN:
|
2009-07-03 00:05:58 +00:00
|
|
|
if (currentMode() <= TEXT_MODE)
|
2006-10-22 10:15:23 +00:00
|
|
|
handleFont(cur, cmd.argument(), "textrm");
|
2005-06-24 10:14:33 +00:00
|
|
|
else
|
2006-10-22 10:15:23 +00:00
|
|
|
handleFont(cur, cmd.argument(), "mathrm");
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2007-09-20 18:02:39 +00:00
|
|
|
case LFUN_FONT_TYPEWRITER:
|
2009-07-03 00:05:58 +00:00
|
|
|
if (currentMode() <= TEXT_MODE)
|
2006-10-22 10:15:23 +00:00
|
|
|
handleFont(cur, cmd.argument(), "texttt");
|
2005-07-15 16:52:27 +00:00
|
|
|
else
|
2006-10-22 10:15:23 +00:00
|
|
|
handleFont(cur, cmd.argument(), "mathtt");
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_FRAK:
|
2006-10-22 10:15:23 +00:00
|
|
|
handleFont(cur, cmd.argument(), "mathfrak");
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_ITAL:
|
2009-07-03 00:05:58 +00:00
|
|
|
if (currentMode() <= TEXT_MODE)
|
2006-10-22 10:15:23 +00:00
|
|
|
handleFont(cur, cmd.argument(), "textit");
|
2005-06-24 10:14:33 +00:00
|
|
|
else
|
2006-10-22 10:15:23 +00:00
|
|
|
handleFont(cur, cmd.argument(), "mathit");
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_NOUN:
|
2009-07-03 00:05:58 +00:00
|
|
|
if (currentMode() <= TEXT_MODE)
|
2005-06-24 10:14:33 +00:00
|
|
|
// FIXME: should be "noun"
|
2006-10-22 10:15:23 +00:00
|
|
|
handleFont(cur, cmd.argument(), "textsc");
|
2005-06-24 10:14:33 +00:00
|
|
|
else
|
2006-10-22 10:15:23 +00:00
|
|
|
handleFont(cur, cmd.argument(), "mathbb");
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_DEFAULT:
|
2006-10-22 10:15:23 +00:00
|
|
|
handleFont(cur, cmd.argument(), "textnormal");
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2004-01-26 10:13:15 +00:00
|
|
|
|
2009-08-12 22:09:50 +00:00
|
|
|
case LFUN_FONT_UNDERLINE:
|
|
|
|
cur.recordUndo();
|
2009-11-08 11:45:46 +00:00
|
|
|
cur.handleNest(createInsetMath("underline", cur.buffer()));
|
2009-08-12 22:09:50 +00:00
|
|
|
break;
|
2006-03-20 14:42:04 +00:00
|
|
|
case LFUN_MATH_MODE: {
|
2004-01-30 11:41:12 +00:00
|
|
|
#if 1
|
2004-11-07 09:39:34 +00:00
|
|
|
// ignore math-mode on when already in math mode
|
2007-04-29 13:39:47 +00:00
|
|
|
if (currentMode() == Inset::MATH_MODE && cmd.argument() == "on")
|
2004-11-07 09:39:34 +00:00
|
|
|
break;
|
2008-08-15 15:50:42 +00:00
|
|
|
cur.recordUndoSelection();
|
2004-01-30 11:41:12 +00:00
|
|
|
cur.macroModeClose();
|
2006-10-22 10:15:23 +00:00
|
|
|
docstring const save_selection = grabAndEraseSelection(cur);
|
2004-04-18 07:34:15 +00:00
|
|
|
selClearOrDel(cur);
|
2009-07-03 00:05:58 +00:00
|
|
|
if (currentMode() <= Inset::TEXT_MODE)
|
2009-11-08 11:45:46 +00:00
|
|
|
cur.plainInsert(MathAtom(new InsetMathEnsureMath(buffer_)));
|
2009-05-20 14:52:03 +00:00
|
|
|
else
|
2009-11-08 11:45:46 +00:00
|
|
|
cur.plainInsert(MathAtom(new InsetMathBox(buffer_, from_ascii("mbox"))));
|
2007-11-05 19:41:16 +00:00
|
|
|
cur.posBackward();
|
|
|
|
cur.pushBackward(*cur.nextInset());
|
2006-03-20 14:42:04 +00:00
|
|
|
cur.niceInsert(save_selection);
|
2010-07-09 14:37:00 +00:00
|
|
|
cur.forceBufferUpdate();
|
2004-01-30 11:41:12 +00:00
|
|
|
#else
|
2007-04-29 13:39:47 +00:00
|
|
|
if (currentMode() == Inset::TEXT_MODE) {
|
2008-08-15 15:50:42 +00:00
|
|
|
cur.recordUndoSelection();
|
2009-11-06 15:18:48 +00:00
|
|
|
cur.niceInsert(MathAtom(new InsetMathHull("simple", cur.buffer())));
|
2004-04-18 19:41:40 +00:00
|
|
|
cur.message(_("create new math text environment ($...$)"));
|
|
|
|
} else {
|
2006-10-22 10:15:23 +00:00
|
|
|
handleFont(cur, cmd.argument(), "textrm");
|
2004-04-18 19:41:40 +00:00
|
|
|
cur.message(_("entered math text mode (textrm)"));
|
|
|
|
}
|
2004-01-30 11:41:12 +00:00
|
|
|
#endif
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2006-03-20 14:42:04 +00:00
|
|
|
}
|
2004-01-26 10:13:15 +00:00
|
|
|
|
2008-11-16 00:18:52 +00:00
|
|
|
case LFUN_REGEXP_MODE: {
|
2010-10-27 07:04:58 +00:00
|
|
|
InsetMath * im = cur.inset().asInsetMath();
|
|
|
|
if (im) {
|
2014-12-29 20:13:42 +00:00
|
|
|
InsetMathHull * i = im->asHullInset();
|
2010-10-27 07:04:58 +00:00
|
|
|
if (i && i->getType() == hullRegexp) {
|
|
|
|
cur.message(_("Already in regular expression mode"));
|
|
|
|
break;
|
|
|
|
}
|
2008-11-16 00:18:52 +00:00
|
|
|
}
|
|
|
|
cur.macroModeClose();
|
|
|
|
docstring const save_selection = grabAndEraseSelection(cur);
|
|
|
|
selClearOrDel(cur);
|
2009-11-08 11:45:46 +00:00
|
|
|
cur.plainInsert(MathAtom(new InsetMathHull(buffer_, hullRegexp)));
|
2008-11-16 00:18:52 +00:00
|
|
|
cur.posBackward();
|
|
|
|
cur.pushBackward(*cur.nextInset());
|
|
|
|
cur.niceInsert(save_selection);
|
2010-01-28 19:56:12 +00:00
|
|
|
cur.message(_("Regular expression editor mode"));
|
2008-11-16 00:18:52 +00:00
|
|
|
break;
|
2010-01-28 20:03:09 +00:00
|
|
|
}
|
2008-11-16 00:18:52 +00:00
|
|
|
|
2009-01-16 10:35:57 +00:00
|
|
|
case LFUN_MATH_FONT_STYLE: {
|
|
|
|
FuncRequest fr = FuncRequest(LFUN_MATH_INSERT, '\\' + cmd.argument());
|
|
|
|
doDispatch(cur, fr);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2008-06-14 18:38:14 +00:00
|
|
|
case LFUN_MATH_SIZE: {
|
|
|
|
FuncRequest fr = FuncRequest(LFUN_MATH_INSERT, cmd.argument());
|
|
|
|
doDispatch(cur, fr);
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2008-06-14 18:38:14 +00:00
|
|
|
}
|
2004-01-26 10:13:15 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_MATH_MATRIX: {
|
2007-10-18 11:51:17 +00:00
|
|
|
cur.recordUndo();
|
2004-01-26 10:13:15 +00:00
|
|
|
unsigned int m = 1;
|
|
|
|
unsigned int n = 1;
|
2006-10-22 10:15:23 +00:00
|
|
|
docstring v_align;
|
|
|
|
docstring h_align;
|
|
|
|
idocstringstream is(cmd.argument());
|
2004-01-26 10:13:15 +00:00
|
|
|
is >> m >> n >> v_align >> h_align;
|
2004-01-30 11:41:12 +00:00
|
|
|
if (m < 1)
|
|
|
|
m = 1;
|
|
|
|
if (n < 1)
|
|
|
|
n = 1;
|
2004-01-26 10:13:15 +00:00
|
|
|
v_align += 'c';
|
2009-11-08 11:45:46 +00:00
|
|
|
cur.niceInsert(MathAtom(new InsetMathArray(buffer_,
|
|
|
|
from_ascii("array"), m, n, (char)v_align[0], h_align)));
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2004-01-26 10:13:15 +00:00
|
|
|
}
|
|
|
|
|
2009-07-12 21:39:21 +00:00
|
|
|
case LFUN_MATH_AMS_MATRIX: {
|
|
|
|
cur.recordUndo();
|
|
|
|
unsigned int m = 1;
|
|
|
|
unsigned int n = 1;
|
2014-02-10 08:23:17 +00:00
|
|
|
docstring name = from_ascii("matrix");
|
2009-07-12 21:39:21 +00:00
|
|
|
idocstringstream is(cmd.argument());
|
|
|
|
is >> m >> n >> name;
|
|
|
|
if (m < 1)
|
|
|
|
m = 1;
|
|
|
|
if (n < 1)
|
|
|
|
n = 1;
|
2014-02-10 08:23:17 +00:00
|
|
|
// check if we have a valid decoration
|
|
|
|
if (name != "pmatrix" && name != "bmatrix"
|
|
|
|
&& name != "Bmatrix" && name != "vmatrix"
|
|
|
|
&& name != "Vmatrix" && name != "matrix")
|
|
|
|
name = from_ascii("matrix");
|
2014-12-29 20:13:42 +00:00
|
|
|
|
2009-07-12 21:39:21 +00:00
|
|
|
cur.niceInsert(
|
2009-11-08 11:45:46 +00:00
|
|
|
MathAtom(new InsetMathAMSArray(buffer_, name, m, n)));
|
2009-07-12 21:39:21 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2004-01-26 10:13:15 +00:00
|
|
|
case LFUN_MATH_DELIM: {
|
2006-10-22 10:15:23 +00:00
|
|
|
docstring ls;
|
2007-12-12 19:57:42 +00:00
|
|
|
docstring rs = split(cmd.argument(), ls, ' ');
|
2004-01-26 10:13:15 +00:00
|
|
|
// Reasonable default values
|
|
|
|
if (ls.empty())
|
|
|
|
ls = '(';
|
|
|
|
if (rs.empty())
|
|
|
|
rs = ')';
|
2007-10-18 11:51:17 +00:00
|
|
|
cur.recordUndo();
|
2009-11-08 11:45:46 +00:00
|
|
|
cur.handleNest(MathAtom(new InsetMathDelim(buffer_, ls, rs)));
|
2006-05-07 10:51:19 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case LFUN_MATH_BIGDELIM: {
|
2006-10-22 10:15:23 +00:00
|
|
|
docstring const lname = from_utf8(cmd.getArg(0));
|
|
|
|
docstring const ldelim = from_utf8(cmd.getArg(1));
|
|
|
|
docstring const rname = from_utf8(cmd.getArg(2));
|
|
|
|
docstring const rdelim = from_utf8(cmd.getArg(3));
|
2006-05-07 10:51:19 +00:00
|
|
|
latexkeys const * l = in_word_set(lname);
|
|
|
|
bool const have_l = l && l->inset == "big" &&
|
2006-09-16 18:11:38 +00:00
|
|
|
InsetMathBig::isBigInsetDelim(ldelim);
|
2006-05-07 10:51:19 +00:00
|
|
|
l = in_word_set(rname);
|
|
|
|
bool const have_r = l && l->inset == "big" &&
|
2006-09-16 18:11:38 +00:00
|
|
|
InsetMathBig::isBigInsetDelim(rdelim);
|
2006-05-07 10:51:19 +00:00
|
|
|
// We mimic LFUN_MATH_DELIM in case we have an empty left
|
|
|
|
// or right delimiter.
|
|
|
|
if (have_l || have_r) {
|
2007-10-18 11:51:17 +00:00
|
|
|
cur.recordUndo();
|
2006-10-22 10:15:23 +00:00
|
|
|
docstring const selection = grabAndEraseSelection(cur);
|
2006-05-07 10:51:19 +00:00
|
|
|
selClearOrDel(cur);
|
|
|
|
if (have_l)
|
2006-09-16 18:11:38 +00:00
|
|
|
cur.insert(MathAtom(new InsetMathBig(lname,
|
2006-05-07 10:51:19 +00:00
|
|
|
ldelim)));
|
2010-11-28 17:16:11 +00:00
|
|
|
// first insert the right delimiter and then go back
|
|
|
|
// and re-insert the selection (bug 7088)
|
|
|
|
if (have_r) {
|
2006-09-16 18:11:38 +00:00
|
|
|
cur.insert(MathAtom(new InsetMathBig(rname,
|
2006-05-07 10:51:19 +00:00
|
|
|
rdelim)));
|
2010-11-28 17:16:11 +00:00
|
|
|
cur.posBackward();
|
|
|
|
}
|
|
|
|
cur.niceInsert(selection);
|
2006-05-07 10:51:19 +00:00
|
|
|
}
|
|
|
|
// Don't call cur.undispatched() if we did nothing, this would
|
2007-04-29 23:33:02 +00:00
|
|
|
// lead to infinite recursion via Text::dispatch().
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2004-01-26 10:13:15 +00:00
|
|
|
}
|
|
|
|
|
2011-10-23 20:19:49 +00:00
|
|
|
case LFUN_SPACE_INSERT: {
|
2008-03-12 00:59:29 +00:00
|
|
|
cur.recordUndoSelection();
|
2011-10-23 20:19:49 +00:00
|
|
|
string const name = cmd.getArg(0);
|
|
|
|
if (name == "normal")
|
|
|
|
cur.insert(MathAtom(new InsetMathSpace(" ", "")));
|
|
|
|
else if (name == "protected")
|
|
|
|
cur.insert(MathAtom(new InsetMathSpace("~", "")));
|
|
|
|
else if (name == "thin" || name == "med" || name == "thick")
|
|
|
|
cur.insert(MathAtom(new InsetMathSpace(name + "space", "")));
|
|
|
|
else if (name == "hfill*")
|
|
|
|
cur.insert(MathAtom(new InsetMathSpace("hspace*{\\fill}", "")));
|
|
|
|
else if (name == "quad" || name == "qquad" ||
|
|
|
|
name == "enspace" || name == "enskip" ||
|
|
|
|
name == "negthinspace" || name == "negmedspace" ||
|
|
|
|
name == "negthickspace" || name == "hfill")
|
|
|
|
cur.insert(MathAtom(new InsetMathSpace(name, "")));
|
|
|
|
else if (name == "hspace" || name == "hspace*") {
|
|
|
|
string const len = cmd.getArg(1);
|
|
|
|
if (len.empty() || !isValidLength(len)) {
|
|
|
|
lyxerr << "LyX function 'space-insert " << name << "' "
|
|
|
|
"needs a valid length argument." << endl;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
cur.insert(MathAtom(new InsetMathSpace(name, len)));
|
|
|
|
} else
|
|
|
|
cur.insert(MathAtom(new InsetMathSpace));
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2011-10-23 20:19:49 +00:00
|
|
|
}
|
2004-01-26 10:13:15 +00:00
|
|
|
|
2008-06-15 22:12:40 +00:00
|
|
|
case LFUN_MATH_SPACE:
|
|
|
|
cur.recordUndoSelection();
|
|
|
|
if (cmd.argument().empty())
|
2008-12-22 18:12:32 +00:00
|
|
|
cur.insert(MathAtom(new InsetMathSpace));
|
2008-12-23 17:25:11 +00:00
|
|
|
else {
|
|
|
|
string const name = cmd.getArg(0);
|
|
|
|
string const len = cmd.getArg(1);
|
|
|
|
cur.insert(MathAtom(new InsetMathSpace(name, len)));
|
|
|
|
}
|
2008-06-15 22:12:40 +00:00
|
|
|
break;
|
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_ERT_INSERT:
|
2004-01-26 10:13:15 +00:00
|
|
|
// interpret this as if a backslash was typed
|
2007-10-18 11:51:17 +00:00
|
|
|
cur.recordUndo();
|
2006-10-19 16:38:13 +00:00
|
|
|
interpretChar(cur, '\\');
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2005-01-06 16:07:02 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_MATH_SUBSCRIPT:
|
2005-01-04 09:18:48 +00:00
|
|
|
// interpret this as if a _ was typed
|
2008-03-12 00:59:29 +00:00
|
|
|
cur.recordUndoSelection();
|
2006-10-19 16:38:13 +00:00
|
|
|
interpretChar(cur, '_');
|
2005-01-04 09:18:48 +00:00
|
|
|
break;
|
2005-01-06 16:07:02 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_MATH_SUPERSCRIPT:
|
2005-01-04 09:18:48 +00:00
|
|
|
// interpret this as if a ^ was typed
|
2008-03-12 00:59:29 +00:00
|
|
|
cur.recordUndoSelection();
|
2006-10-19 16:38:13 +00:00
|
|
|
interpretChar(cur, '^');
|
2005-01-04 09:18:48 +00:00
|
|
|
break;
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2007-11-01 11:14:14 +00:00
|
|
|
case LFUN_MATH_MACRO_FOLD:
|
|
|
|
case LFUN_MATH_MACRO_UNFOLD: {
|
|
|
|
Cursor it = cur;
|
2010-04-09 19:00:42 +00:00
|
|
|
bool fold = act == LFUN_MATH_MACRO_FOLD;
|
2007-11-01 11:14:14 +00:00
|
|
|
bool found = findMacroToFoldUnfold(it, fold);
|
|
|
|
if (found) {
|
2007-12-21 20:42:46 +00:00
|
|
|
MathMacro * macro = it.nextInset()->asInsetMath()->asMacro();
|
|
|
|
cur.recordUndoInset();
|
2007-11-01 11:14:14 +00:00
|
|
|
if (fold)
|
2007-12-21 20:42:46 +00:00
|
|
|
macro->fold(cur);
|
2007-11-01 11:14:14 +00:00
|
|
|
else
|
2007-12-21 20:42:46 +00:00
|
|
|
macro->unfold(cur);
|
|
|
|
}
|
2007-11-01 11:14:14 +00:00
|
|
|
break;
|
|
|
|
}
|
2004-01-26 10:13:15 +00:00
|
|
|
|
2006-12-27 15:01:09 +00:00
|
|
|
case LFUN_QUOTE_INSERT:
|
|
|
|
// interpret this as if a straight " was typed
|
2008-03-12 00:59:29 +00:00
|
|
|
cur.recordUndoSelection();
|
2006-12-27 15:01:09 +00:00
|
|
|
interpretChar(cur, '\"');
|
|
|
|
break;
|
|
|
|
|
2004-01-26 10:13:15 +00:00
|
|
|
// FIXME: We probably should swap parts of "math-insert" and "self-insert"
|
|
|
|
// handling such that "self-insert" works on "arbitrary stuff" too, and
|
|
|
|
// math-insert only handles special math things like "matrix".
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_MATH_INSERT: {
|
2008-03-12 00:59:29 +00:00
|
|
|
cur.recordUndoSelection();
|
2008-03-18 10:58:57 +00:00
|
|
|
if (cmd.argument() == "^" || cmd.argument() == "_")
|
2006-10-19 18:56:16 +00:00
|
|
|
interpretChar(cur, cmd.argument()[0]);
|
2008-03-18 10:58:57 +00:00
|
|
|
else {
|
|
|
|
MathData ar;
|
|
|
|
asArray(cmd.argument(), ar);
|
2009-06-23 18:01:31 +00:00
|
|
|
if (cur.selection() && ar.size() == 1
|
|
|
|
&& ar[0]->asNestInset()
|
|
|
|
&& ar[0]->asNestInset()->nargs() > 1)
|
2008-03-18 10:58:57 +00:00
|
|
|
handleNest(cur, ar[0]);
|
|
|
|
else
|
|
|
|
cur.niceInsert(cmd.argument());
|
|
|
|
}
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2010-04-30 22:23:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
case LFUN_UNICODE_INSERT: {
|
|
|
|
if (cmd.argument().empty())
|
|
|
|
break;
|
|
|
|
docstring hexstring = cmd.argument();
|
|
|
|
if (isHex(hexstring)) {
|
|
|
|
char_type c = hexToInt(hexstring);
|
|
|
|
if (c >= 32 && c < 0x10ffff) {
|
|
|
|
docstring s = docstring(1, c);
|
|
|
|
FuncCode code = currentMode() == MATH_MODE ?
|
|
|
|
LFUN_MATH_INSERT : LFUN_SELF_INSERT;
|
|
|
|
lyx::dispatch(FuncRequest(code, s));
|
|
|
|
}
|
2005-04-06 19:01:55 +00:00
|
|
|
}
|
2010-04-30 22:23:19 +00:00
|
|
|
break;
|
|
|
|
}
|
2004-01-26 10:13:15 +00:00
|
|
|
|
|
|
|
case LFUN_DIALOG_SHOW_NEW_INSET: {
|
2006-10-22 10:15:23 +00:00
|
|
|
docstring const & name = cmd.argument();
|
2004-01-26 10:13:15 +00:00
|
|
|
string data;
|
|
|
|
if (name == "ref") {
|
2009-11-08 11:45:46 +00:00
|
|
|
InsetMathRef tmp(buffer_, name);
|
2010-10-29 00:42:40 +00:00
|
|
|
data = tmp.createDialogStr();
|
2010-02-21 09:28:33 +00:00
|
|
|
cur.bv().showDialog(to_utf8(name), data);
|
2008-12-22 18:12:32 +00:00
|
|
|
} else if (name == "mathspace") {
|
2010-02-21 09:28:33 +00:00
|
|
|
cur.bv().showDialog(to_utf8(name));
|
2004-01-26 10:13:15 +00:00
|
|
|
}
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2004-01-26 10:13:15 +00:00
|
|
|
}
|
|
|
|
|
2006-09-30 17:17:31 +00:00
|
|
|
case LFUN_INSET_INSERT: {
|
2007-04-26 16:05:57 +00:00
|
|
|
MathData ar;
|
2006-10-22 10:15:23 +00:00
|
|
|
if (createInsetMath_fromDialogStr(cmd.argument(), ar)) {
|
2008-03-12 00:59:29 +00:00
|
|
|
cur.recordUndoSelection();
|
2006-09-30 17:17:31 +00:00
|
|
|
cur.insert(ar);
|
2014-12-29 20:13:42 +00:00
|
|
|
cur.forceBufferUpdate();
|
2006-09-30 17:17:31 +00:00
|
|
|
} else
|
|
|
|
cur.undispatched();
|
|
|
|
break;
|
|
|
|
}
|
2007-10-03 10:24:37 +00:00
|
|
|
case LFUN_INSET_DISSOLVE:
|
|
|
|
if (!asHullInset()) {
|
2007-10-18 11:51:17 +00:00
|
|
|
cur.recordUndoInset();
|
2007-10-03 10:24:37 +00:00
|
|
|
cur.pullArg();
|
|
|
|
}
|
|
|
|
break;
|
2006-09-30 17:17:31 +00:00
|
|
|
|
2004-01-20 14:25:24 +00:00
|
|
|
default:
|
2007-04-30 10:31:51 +00:00
|
|
|
InsetMath::doDispatch(cur, cmd);
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2002-08-15 10:02:53 +00:00
|
|
|
}
|
|
|
|
}
|
2003-05-28 13:22:36 +00:00
|
|
|
|
|
|
|
|
2007-11-01 11:14:14 +00:00
|
|
|
bool InsetMathNest::findMacroToFoldUnfold(Cursor & it, bool fold) const {
|
|
|
|
// look for macro to open/close, but stay in mathed
|
|
|
|
for (; !it.empty(); it.pop_back()) {
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2007-11-01 11:14:14 +00:00
|
|
|
// go backward through the current cell
|
|
|
|
Inset * inset = it.nextInset();
|
|
|
|
while (inset && inset->asInsetMath()) {
|
|
|
|
MathMacro * macro = inset->asInsetMath()->asMacro();
|
|
|
|
if (macro) {
|
|
|
|
// found the an macro to open/close?
|
|
|
|
if (macro->folded() != fold)
|
|
|
|
return true;
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2007-11-02 00:11:51 +00:00
|
|
|
// Wrong folding state.
|
|
|
|
// If this was the first we see in this slice, look further left,
|
|
|
|
// otherwise go up.
|
|
|
|
if (inset != it.nextInset())
|
|
|
|
break;
|
2007-11-01 11:14:14 +00:00
|
|
|
}
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2007-11-01 11:14:14 +00:00
|
|
|
// go up if this was the left most position
|
|
|
|
if (it.pos() == 0)
|
|
|
|
break;
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2007-11-01 11:14:14 +00:00
|
|
|
// go left
|
|
|
|
it.pos()--;
|
|
|
|
inset = it.nextInset();
|
|
|
|
}
|
|
|
|
}
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2007-11-01 11:14:14 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
bool InsetMathNest::getStatus(Cursor & cur, FuncRequest const & cmd,
|
2004-03-18 13:57:20 +00:00
|
|
|
FuncStatus & flag) const
|
|
|
|
{
|
|
|
|
// the font related toggles
|
2004-04-20 08:44:30 +00:00
|
|
|
//string tc = "mathnormal";
|
2004-03-18 13:57:20 +00:00
|
|
|
bool ret = true;
|
2006-10-21 00:16:43 +00:00
|
|
|
string const arg = to_utf8(cmd.argument());
|
2010-04-09 19:00:42 +00:00
|
|
|
switch (cmd.action()) {
|
2010-02-18 08:28:46 +00:00
|
|
|
case LFUN_INSET_MODIFY:
|
2008-05-29 15:14:00 +00:00
|
|
|
flag.setEnabled(false);
|
2005-04-25 14:10:10 +00:00
|
|
|
break;
|
2004-03-18 13:57:20 +00:00
|
|
|
#if 0
|
2010-02-18 08:28:46 +00:00
|
|
|
case LFUN_INSET_MODIFY:
|
2004-03-18 13:57:20 +00:00
|
|
|
// FIXME: check temporarily disabled
|
|
|
|
// valign code
|
|
|
|
char align = mathcursor::valign();
|
|
|
|
if (align == '\0') {
|
|
|
|
enable = false;
|
|
|
|
break;
|
|
|
|
}
|
2006-09-01 15:41:38 +00:00
|
|
|
if (cmd.argument().empty()) {
|
2004-03-18 13:57:20 +00:00
|
|
|
flag.clear();
|
|
|
|
break;
|
|
|
|
}
|
2006-09-01 15:41:38 +00:00
|
|
|
if (!contains("tcb", cmd.argument()[0])) {
|
2004-03-18 13:57:20 +00:00
|
|
|
enable = false;
|
|
|
|
break;
|
|
|
|
}
|
2006-09-01 15:41:38 +00:00
|
|
|
flag.setOnOff(cmd.argument()[0] == align);
|
2004-03-18 13:57:20 +00:00
|
|
|
break;
|
2005-07-15 16:52:27 +00:00
|
|
|
#endif
|
|
|
|
/// We have to handle them since 1.4 blocks all unhandled actions
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_ITAL:
|
|
|
|
case LFUN_FONT_BOLD:
|
2008-09-15 16:49:11 +00:00
|
|
|
case LFUN_FONT_BOLDSYMBOL:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_SANS:
|
|
|
|
case LFUN_FONT_EMPH:
|
2007-09-20 18:02:39 +00:00
|
|
|
case LFUN_FONT_TYPEWRITER:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_NOUN:
|
|
|
|
case LFUN_FONT_ROMAN:
|
|
|
|
case LFUN_FONT_DEFAULT:
|
2008-05-29 15:14:00 +00:00
|
|
|
flag.setEnabled(true);
|
2004-03-18 13:57:20 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
// we just need to be in math mode to enable that
|
|
|
|
case LFUN_MATH_SIZE:
|
|
|
|
case LFUN_MATH_SPACE:
|
|
|
|
case LFUN_MATH_EXTERN:
|
2008-05-29 15:14:00 +00:00
|
|
|
flag.setEnabled(true);
|
2004-03-18 13:57:20 +00:00
|
|
|
break;
|
2005-06-24 10:14:33 +00:00
|
|
|
|
2009-08-12 22:09:50 +00:00
|
|
|
case LFUN_FONT_UNDERLINE:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_FRAK:
|
2008-05-29 15:14:00 +00:00
|
|
|
flag.setEnabled(currentMode() != TEXT_MODE);
|
2005-06-24 10:14:33 +00:00
|
|
|
break;
|
|
|
|
|
2009-01-16 10:35:57 +00:00
|
|
|
case LFUN_MATH_FONT_STYLE: {
|
2005-06-09 09:58:08 +00:00
|
|
|
bool const textarg =
|
2009-01-16 10:35:57 +00:00
|
|
|
arg == "textbf" || arg == "textsf" ||
|
|
|
|
arg == "textrm" || arg == "textmd" ||
|
|
|
|
arg == "textit" || arg == "textsc" ||
|
|
|
|
arg == "textsl" || arg == "textup" ||
|
|
|
|
arg == "texttt" || arg == "textbb" ||
|
|
|
|
arg == "textnormal";
|
2008-05-29 15:14:00 +00:00
|
|
|
flag.setEnabled(currentMode() != TEXT_MODE || textarg);
|
2005-05-01 16:15:32 +00:00
|
|
|
break;
|
|
|
|
}
|
2005-06-24 10:14:33 +00:00
|
|
|
|
2010-12-04 16:43:41 +00:00
|
|
|
case LFUN_MATH_MODE:
|
|
|
|
// forbid "math-mode on" in math mode to prevent irritating
|
|
|
|
// behaviour of menu entries (bug 6709)
|
|
|
|
flag.setEnabled(currentMode() == TEXT_MODE || arg != "on");
|
|
|
|
break;
|
|
|
|
|
2009-01-16 10:35:57 +00:00
|
|
|
case LFUN_MATH_INSERT:
|
|
|
|
flag.setEnabled(currentMode() != TEXT_MODE);
|
|
|
|
break;
|
|
|
|
|
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:
|
2008-05-29 15:14:00 +00:00
|
|
|
flag.setEnabled(currentMode() == MATH_MODE);
|
2005-05-01 16:15:32 +00:00
|
|
|
break;
|
2006-05-07 10:51:19 +00:00
|
|
|
|
2006-09-30 17:17:31 +00:00
|
|
|
case LFUN_INSET_INSERT: {
|
|
|
|
// Don't test createMathInset_fromDialogStr(), since
|
|
|
|
// getStatus is not called with a valid reference and the
|
|
|
|
// dialog would not be applyable.
|
|
|
|
string const name = cmd.getArg(0);
|
2008-12-22 18:12:32 +00:00
|
|
|
flag.setEnabled(name == "ref" || name == "mathspace");
|
2006-09-30 17:17:31 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2011-08-27 10:45:59 +00:00
|
|
|
case LFUN_DIALOG_SHOW_NEW_INSET: {
|
|
|
|
docstring const & name = cmd.argument();
|
|
|
|
if (name == "space")
|
|
|
|
flag.setEnabled(false);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-05-07 10:51:19 +00:00
|
|
|
case LFUN_MATH_DELIM:
|
|
|
|
case LFUN_MATH_BIGDELIM:
|
|
|
|
// Don't do this with multi-cell selections
|
2008-05-29 15:14:00 +00:00
|
|
|
flag.setEnabled(cur.selBegin().idx() == cur.selEnd().idx());
|
2006-05-07 10:51:19 +00:00
|
|
|
break;
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2007-11-01 11:14:14 +00:00
|
|
|
case LFUN_MATH_MACRO_FOLD:
|
|
|
|
case LFUN_MATH_MACRO_UNFOLD: {
|
|
|
|
Cursor it = cur;
|
2010-04-09 19:00:42 +00:00
|
|
|
bool found = findMacroToFoldUnfold(it, cmd.action() == LFUN_MATH_MACRO_FOLD);
|
2008-05-29 15:14:00 +00:00
|
|
|
flag.setEnabled(found);
|
2007-11-01 11:14:14 +00:00
|
|
|
break;
|
|
|
|
}
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2007-12-06 11:04:56 +00:00
|
|
|
case LFUN_SPECIALCHAR_INSERT:
|
2010-11-23 20:09:08 +00:00
|
|
|
case LFUN_SCRIPT_INSERT:
|
2007-05-15 17:33:42 +00:00
|
|
|
// FIXME: These would probably make sense in math-text mode
|
2008-05-29 15:14:00 +00:00
|
|
|
flag.setEnabled(false);
|
2007-05-15 17:33:42 +00:00
|
|
|
break;
|
|
|
|
|
2013-01-05 08:42:27 +00:00
|
|
|
case LFUN_CAPTION_INSERT:
|
|
|
|
flag.setEnabled(false);
|
|
|
|
break;
|
2014-12-29 20:13:42 +00:00
|
|
|
|
2011-08-27 10:58:48 +00:00
|
|
|
case LFUN_SPACE_INSERT: {
|
|
|
|
docstring const & name = cmd.argument();
|
2011-10-23 20:19:49 +00:00
|
|
|
if (name == "visible")
|
2011-08-27 10:58:48 +00:00
|
|
|
flag.setEnabled(false);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2007-10-03 10:24:37 +00:00
|
|
|
case LFUN_INSET_DISSOLVE:
|
2008-05-29 15:14:00 +00:00
|
|
|
flag.setEnabled(!asHullInset());
|
2007-10-03 10:24:37 +00:00
|
|
|
break;
|
|
|
|
|
2013-04-14 17:45:36 +00:00
|
|
|
case LFUN_PASTE: {
|
|
|
|
docstring const & name = cmd.argument();
|
|
|
|
if (name == "html" || name == "latex")
|
|
|
|
flag.setEnabled(false);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2004-03-18 13:57:20 +00:00
|
|
|
default:
|
|
|
|
ret = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2004-03-27 12:46:30 +00:00
|
|
|
|
2008-02-11 08:20:13 +00:00
|
|
|
void InsetMathNest::edit(Cursor & cur, bool front, EntryDirection entry_from)
|
2003-05-28 13:22:36 +00:00
|
|
|
{
|
2004-03-18 12:53:43 +00:00
|
|
|
cur.push(*this);
|
2008-10-13 11:25:37 +00:00
|
|
|
bool enter_front = (entry_from == Inset::ENTRY_DIRECTION_RIGHT ||
|
2008-02-11 08:20:13 +00:00
|
|
|
(entry_from == Inset::ENTRY_DIRECTION_IGNORE && front));
|
2008-02-10 19:52:45 +00:00
|
|
|
cur.idx() = enter_front ? 0 : cur.lastidx();
|
|
|
|
cur.pos() = enter_front ? 0 : cur.lastpos();
|
2004-02-06 16:14:06 +00:00
|
|
|
cur.resetAnchor();
|
2006-09-16 18:11:38 +00:00
|
|
|
//lyxerr << "InsetMathNest::edit, cur:\n" << cur << endl;
|
2004-02-06 16:14:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-29 13:39:47 +00:00
|
|
|
Inset * InsetMathNest::editXY(Cursor & cur, int x, int y)
|
2004-02-06 16:14:06 +00:00
|
|
|
{
|
2004-01-30 11:41:12 +00:00
|
|
|
int idx_min = 0;
|
|
|
|
int dist_min = 1000000;
|
2005-07-15 00:39:44 +00:00
|
|
|
for (idx_type i = 0, n = nargs(); i != n; ++i) {
|
2006-10-13 16:44:44 +00:00
|
|
|
int const d = cell(i).dist(cur.bv(), x, y);
|
2004-01-30 11:41:12 +00:00
|
|
|
if (d < dist_min) {
|
|
|
|
dist_min = d;
|
|
|
|
idx_min = i;
|
|
|
|
}
|
|
|
|
}
|
2007-04-26 16:05:57 +00:00
|
|
|
MathData & ar = cell(idx_min);
|
2005-07-15 00:39:44 +00:00
|
|
|
cur.push(*this);
|
2004-01-30 11:41:12 +00:00
|
|
|
cur.idx() = idx_min;
|
2007-12-24 10:52:58 +00:00
|
|
|
cur.pos() = ar.x2pos(&cur.bv(), x - ar.xo(cur.bv()));
|
2006-10-13 16:44:44 +00:00
|
|
|
|
2005-07-15 08:51:34 +00:00
|
|
|
//lyxerr << "found cell : " << idx_min << " pos: " << cur.pos() << endl;
|
2004-01-30 11:41:12 +00:00
|
|
|
if (dist_min == 0) {
|
|
|
|
// hit inside cell
|
|
|
|
for (pos_type i = 0, n = ar.size(); i < n; ++i)
|
2006-10-13 16:44:44 +00:00
|
|
|
if (ar[i]->covers(cur.bv(), x, y))
|
2004-02-13 13:51:12 +00:00
|
|
|
return ar[i].nucleus()->editXY(cur, x, y);
|
2004-01-30 11:41:12 +00:00
|
|
|
}
|
2005-07-15 00:39:44 +00:00
|
|
|
return this;
|
2003-05-28 13:22:36 +00:00
|
|
|
}
|
2004-02-06 16:14:06 +00:00
|
|
|
|
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
void InsetMathNest::lfunMousePress(Cursor & cur, FuncRequest & cmd)
|
2004-02-06 16:14:06 +00:00
|
|
|
{
|
2005-02-28 11:32:58 +00:00
|
|
|
//lyxerr << "## lfunMousePress: buttons: " << cmd.button() << endl;
|
2006-08-22 13:58:09 +00:00
|
|
|
BufferView & bv = cur.bv();
|
2011-03-19 13:14:13 +00:00
|
|
|
if (cmd.button() == mouse_button::button3) {
|
|
|
|
// Don't do anything if we right-click a
|
|
|
|
// selection, a context menu will popup.
|
|
|
|
if (bv.cursor().selection() && cur >= bv.cursor().selectionBegin()
|
|
|
|
&& cur < bv.cursor().selectionEnd()) {
|
|
|
|
cur.noScreenUpdate();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2007-10-13 09:04:52 +00:00
|
|
|
bool do_selection = cmd.button() == mouse_button::button1
|
|
|
|
&& cmd.argument() == "region-select";
|
|
|
|
bv.mouseSetCursor(cur, do_selection);
|
2004-02-06 16:14:06 +00:00
|
|
|
if (cmd.button() == mouse_button::button1) {
|
2005-02-28 11:32:58 +00:00
|
|
|
//lyxerr << "## lfunMousePress: setting cursor to: " << cur << endl;
|
2007-04-13 11:35:11 +00:00
|
|
|
// Update the cursor update flags as needed:
|
|
|
|
//
|
2007-08-13 15:38:32 +00:00
|
|
|
// Update::Decoration: tells to update the decoration
|
|
|
|
// (visual box corners that define
|
|
|
|
// the inset)/
|
|
|
|
// Update::FitCursor: adjust the screen to the cursor
|
|
|
|
// position if needed
|
2007-04-13 11:35:11 +00:00
|
|
|
// cur.result().update(): don't overwrite previously set flags.
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.screenUpdateFlags(Update::Decoration | Update::FitCursor
|
2010-10-13 17:28:55 +00:00
|
|
|
| cur.result().screenUpdate());
|
2015-02-08 16:41:28 +00:00
|
|
|
} else if (cmd.button() == mouse_button::button2 && lyxrc.mouse_middlebutton_paste) {
|
2007-02-02 03:10:15 +00:00
|
|
|
if (cap::selection()) {
|
2007-04-29 23:33:02 +00:00
|
|
|
// See comment in Text::dispatch why we do this
|
2007-02-02 03:10:15 +00:00
|
|
|
cap::copySelectionToStack();
|
|
|
|
cmd = FuncRequest(LFUN_PASTE, "0");
|
2007-08-13 15:38:32 +00:00
|
|
|
doDispatch(bv.cursor(), cmd);
|
|
|
|
} else {
|
|
|
|
MathData ar;
|
2006-10-17 14:46:45 +00:00
|
|
|
asArray(theSelection().get(), ar);
|
2007-08-13 15:38:32 +00:00
|
|
|
bv.cursor().insert(ar);
|
|
|
|
}
|
2004-02-06 16:14:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
void InsetMathNest::lfunMouseMotion(Cursor & cur, FuncRequest & cmd)
|
2004-02-06 16:14:06 +00:00
|
|
|
{
|
|
|
|
// only select with button 1
|
2014-04-04 13:40:05 +00:00
|
|
|
if (cmd.button() != mouse_button::button1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Cursor & bvcur = cur.bv().cursor();
|
|
|
|
|
|
|
|
// ignore motions deeper nested than the real anchor
|
|
|
|
if (!bvcur.realAnchor().hasPart(cur)) {
|
|
|
|
cur.undispatched();
|
|
|
|
return;
|
2004-08-14 20:34:46 +00:00
|
|
|
}
|
2014-04-04 13:40:05 +00:00
|
|
|
|
|
|
|
CursorSlice old = bvcur.top();
|
|
|
|
|
|
|
|
// We continue with our existing selection or start a new one, so don't
|
|
|
|
// reset the anchor.
|
|
|
|
bvcur.setCursor(cur);
|
|
|
|
// Did we actually move?
|
|
|
|
if (cur.top() == old)
|
|
|
|
// We didn't move one iota, so no need to change selection status
|
|
|
|
// or update the screen.
|
|
|
|
cur.screenUpdateFlags(Update::SinglePar | Update::FitCursor);
|
|
|
|
else
|
|
|
|
bvcur.setSelection();
|
2004-02-06 16:14:06 +00:00
|
|
|
}
|
2004-02-27 09:18:03 +00:00
|
|
|
|
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
void InsetMathNest::lfunMouseRelease(Cursor & cur, FuncRequest & cmd)
|
2004-08-13 21:21:10 +00:00
|
|
|
{
|
2005-02-28 11:32:58 +00:00
|
|
|
//lyxerr << "## lfunMouseRelease: buttons: " << cmd.button() << endl;
|
2004-08-13 21:21:10 +00:00
|
|
|
|
|
|
|
if (cmd.button() == mouse_button::button1) {
|
2006-11-22 14:45:33 +00:00
|
|
|
if (!cur.selection())
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.noScreenUpdate();
|
2007-02-02 03:10:15 +00:00
|
|
|
else {
|
2007-04-26 14:56:30 +00:00
|
|
|
Cursor & bvcur = cur.bv().cursor();
|
2008-09-24 21:27:41 +00:00
|
|
|
bvcur.setSelection(true);
|
2007-02-02 03:10:15 +00:00
|
|
|
}
|
2004-08-13 21:21:10 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
cur.undispatched();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-11-14 15:58:50 +00:00
|
|
|
bool InsetMathNest::interpretChar(Cursor & cur, char_type const c)
|
2004-02-27 09:18:03 +00:00
|
|
|
{
|
2005-07-15 08:51:34 +00:00
|
|
|
//lyxerr << "interpret 2: '" << c << "'" << endl;
|
2006-10-22 10:15:23 +00:00
|
|
|
docstring save_selection;
|
2006-03-20 06:53:29 +00:00
|
|
|
if (c == '^' || c == '_')
|
2006-03-20 14:42:04 +00:00
|
|
|
save_selection = grabAndEraseSelection(cur);
|
2006-03-20 06:53:29 +00:00
|
|
|
|
2004-02-27 09:18:03 +00:00
|
|
|
cur.clearTargetX();
|
2009-11-08 11:45:46 +00:00
|
|
|
Buffer * buf = cur.buffer();
|
2004-02-27 09:18:03 +00:00
|
|
|
|
|
|
|
// handle macroMode
|
|
|
|
if (cur.inMacroMode()) {
|
2006-10-22 10:15:23 +00:00
|
|
|
docstring name = cur.macroName();
|
2004-04-18 07:34:15 +00:00
|
|
|
|
|
|
|
/// are we currently typing '#1' or '#2' or...?
|
|
|
|
if (name == "\\#") {
|
|
|
|
cur.backspace();
|
|
|
|
int n = c - '0';
|
|
|
|
if (n >= 1 && n <= 9)
|
|
|
|
cur.insert(new MathMacroArgument(n));
|
|
|
|
return true;
|
|
|
|
}
|
2004-02-27 09:18:03 +00:00
|
|
|
|
2008-02-27 10:46:38 +00:00
|
|
|
// do not finish macro for known * commands
|
|
|
|
bool star_macro = c == '*'
|
2014-12-29 20:13:42 +00:00
|
|
|
&& (in_word_set(name.substr(1) + '*')
|
2008-11-17 11:46:07 +00:00
|
|
|
|| cur.buffer()->getMacro(name.substr(1) + "*", cur, true));
|
2008-02-27 10:46:38 +00:00
|
|
|
if (isAlphaASCII(c) || star_macro) {
|
2006-10-22 10:15:23 +00:00
|
|
|
cur.activeMacro()->setName(name + docstring(1, c));
|
2004-02-27 09:18:03 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// handle 'special char' macros
|
|
|
|
if (name == "\\") {
|
|
|
|
// remove the '\\'
|
|
|
|
if (c == '\\') {
|
2004-04-18 07:34:15 +00:00
|
|
|
cur.backspace();
|
2009-07-03 00:05:58 +00:00
|
|
|
if (currentMode() <= InsetMath::TEXT_MODE)
|
2009-11-08 11:45:46 +00:00
|
|
|
cur.niceInsert(createInsetMath("textbackslash", buf));
|
2004-02-27 09:18:03 +00:00
|
|
|
else
|
2009-11-08 11:45:46 +00:00
|
|
|
cur.niceInsert(createInsetMath("backslash", buf));
|
2008-10-23 00:48:06 +00:00
|
|
|
} else if (c == '^' && currentMode() == InsetMath::MATH_MODE) {
|
|
|
|
cur.backspace();
|
2009-11-08 11:45:46 +00:00
|
|
|
cur.niceInsert(createInsetMath("mathcircumflex", buf));
|
2004-02-27 09:18:03 +00:00
|
|
|
} else if (c == '{') {
|
2004-04-18 07:34:15 +00:00
|
|
|
cur.backspace();
|
2009-11-08 11:45:46 +00:00
|
|
|
cur.niceInsert(MathAtom(new InsetMathBrace(buf)));
|
2004-08-12 19:49:25 +00:00
|
|
|
} else if (c == '%') {
|
|
|
|
cur.backspace();
|
2009-11-08 11:45:46 +00:00
|
|
|
cur.niceInsert(MathAtom(new InsetMathComment(buf)));
|
2004-04-18 07:34:15 +00:00
|
|
|
} else if (c == '#') {
|
2013-04-25 21:27:10 +00:00
|
|
|
LASSERT(cur.activeMacro(), return false);
|
2006-10-22 10:15:23 +00:00
|
|
|
cur.activeMacro()->setName(name + docstring(1, c));
|
2004-02-27 09:18:03 +00:00
|
|
|
} else {
|
2004-04-18 07:34:15 +00:00
|
|
|
cur.backspace();
|
2009-11-08 11:45:46 +00:00
|
|
|
cur.niceInsert(createInsetMath(docstring(1, c), buf));
|
2004-02-27 09:18:03 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2006-04-20 09:55:45 +00:00
|
|
|
// One character big delimiters. The others are handled in
|
2006-10-19 18:56:16 +00:00
|
|
|
// interpretString().
|
2006-04-20 09:55:45 +00:00
|
|
|
latexkeys const * l = in_word_set(name.substr(1));
|
|
|
|
if (name[0] == '\\' && l && l->inset == "big") {
|
2006-10-22 10:15:23 +00:00
|
|
|
docstring delim;
|
2006-04-20 09:55:45 +00:00
|
|
|
switch (c) {
|
|
|
|
case '{':
|
2006-10-22 10:15:23 +00:00
|
|
|
delim = from_ascii("\\{");
|
2006-04-20 09:55:45 +00:00
|
|
|
break;
|
|
|
|
case '}':
|
2006-10-22 10:15:23 +00:00
|
|
|
delim = from_ascii("\\}");
|
2006-04-20 09:55:45 +00:00
|
|
|
break;
|
|
|
|
default:
|
2006-10-22 10:15:23 +00:00
|
|
|
delim = docstring(1, c);
|
2006-04-20 09:55:45 +00:00
|
|
|
break;
|
|
|
|
}
|
2006-09-16 18:11:38 +00:00
|
|
|
if (InsetMathBig::isBigInsetDelim(delim)) {
|
|
|
|
// name + delim ared a valid InsetMathBig.
|
2006-04-20 09:55:45 +00:00
|
|
|
// We can't use cur.macroModeClose() because
|
|
|
|
// it does not handle delim.
|
2006-09-16 18:11:38 +00:00
|
|
|
InsetMathUnknown * p = cur.activeMacro();
|
2006-04-20 09:55:45 +00:00
|
|
|
p->finalize();
|
|
|
|
--cur.pos();
|
|
|
|
cur.cell().erase(cur.pos());
|
|
|
|
cur.plainInsert(MathAtom(
|
2006-09-16 18:11:38 +00:00
|
|
|
new InsetMathBig(name.substr(1), delim)));
|
2006-04-20 09:55:45 +00:00
|
|
|
return true;
|
|
|
|
}
|
2014-02-21 20:31:35 +00:00
|
|
|
} else if (name == "\\smash" && c == '[') {
|
|
|
|
// We can't use cur.macroModeClose() because
|
|
|
|
// it would create an InsetMathPhantom
|
|
|
|
InsetMathUnknown * p = cur.activeMacro();
|
|
|
|
p->finalize();
|
|
|
|
interpretChar(cur, c);
|
|
|
|
return true;
|
2006-04-20 09:55:45 +00:00
|
|
|
}
|
|
|
|
|
2004-02-27 09:18:03 +00:00
|
|
|
// leave macro mode and try again if necessary
|
2009-05-15 22:00:43 +00:00
|
|
|
if (cur.macroModeClose()) {
|
|
|
|
MathAtom const atom = cur.prevAtom();
|
|
|
|
if (atom->asNestInset() && atom->isActive()) {
|
|
|
|
cur.posBackward();
|
|
|
|
cur.pushBackward(*cur.nextInset());
|
|
|
|
}
|
|
|
|
}
|
2004-02-27 09:18:03 +00:00
|
|
|
if (c == '{')
|
2009-11-08 11:45:46 +00:00
|
|
|
cur.niceInsert(MathAtom(new InsetMathBrace(buf)));
|
2004-02-27 09:18:03 +00:00
|
|
|
else if (c != ' ')
|
2006-10-19 16:38:13 +00:00
|
|
|
interpretChar(cur, c);
|
2004-02-27 09:18:03 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-15 09:48:00 +00:00
|
|
|
// leave autocorrect mode if necessary
|
|
|
|
if (lyxrc.autocorrection_math && c == ' ' && cur.autocorrect()) {
|
|
|
|
cur.autocorrect() = false;
|
|
|
|
cur.message(_("Autocorrect Off ('!' to enter)"));
|
|
|
|
return true;
|
2014-12-29 20:13:42 +00:00
|
|
|
}
|
2009-01-15 09:48:00 +00:00
|
|
|
if (lyxrc.autocorrection_math && c == '!' && !cur.autocorrect()) {
|
|
|
|
cur.autocorrect() = true;
|
|
|
|
cur.message(_("Autocorrect On (<space> to exit)"));
|
|
|
|
return true;
|
|
|
|
}
|
2004-02-27 09:18:03 +00:00
|
|
|
|
|
|
|
// just clear selection on pressing the space bar
|
|
|
|
if (cur.selection() && c == ' ') {
|
2008-09-24 21:27:41 +00:00
|
|
|
cur.setSelection(false);
|
2004-02-27 09:18:03 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (c == '\\') {
|
|
|
|
//lyxerr << "starting with macro" << endl;
|
2008-03-12 00:18:39 +00:00
|
|
|
bool reduced = cap::reduceSelectionToOneCell(cur);
|
|
|
|
if (reduced || !cur.selection()) {
|
2012-04-17 08:55:59 +00:00
|
|
|
cur.recordUndoInset();
|
2008-03-12 00:18:39 +00:00
|
|
|
docstring const safe = cap::grabAndEraseSelection(cur);
|
2012-04-13 11:03:59 +00:00
|
|
|
if (!cur.inRegexped())
|
2011-06-12 01:19:07 +00:00
|
|
|
cur.insert(MathAtom(new InsetMathUnknown(from_ascii("\\"), safe, false)));
|
2012-04-13 11:03:59 +00:00
|
|
|
else
|
2011-06-12 01:19:07 +00:00
|
|
|
cur.niceInsert(createInsetMath("backslash", buf));
|
2008-03-12 00:18:39 +00:00
|
|
|
}
|
2004-02-27 09:18:03 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-07-07 08:13:07 +00:00
|
|
|
selClearOrDel(cur);
|
|
|
|
|
2004-02-27 09:18:03 +00:00
|
|
|
if (c == '\n') {
|
2009-07-03 00:05:58 +00:00
|
|
|
if (currentMode() <= InsetMath::TEXT_MODE)
|
2004-02-27 09:18:03 +00:00
|
|
|
cur.insert(c);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (c == ' ') {
|
2009-07-03 00:05:58 +00:00
|
|
|
if (currentMode() <= InsetMath::TEXT_MODE) {
|
|
|
|
// insert spaces in text or undecided mode,
|
2004-02-27 09:18:03 +00:00
|
|
|
// but suppress direct insertion of two spaces in a row
|
|
|
|
// the still allows typing '<space>a<space>' and deleting the 'a', but
|
|
|
|
// it is better than nothing...
|
2014-04-21 14:50:56 +00:00
|
|
|
if (cur.pos() == 0 || cur.prevAtom()->getChar() != ' ') {
|
2004-02-27 09:18:03 +00:00
|
|
|
cur.insert(c);
|
2006-11-22 14:45:33 +00:00
|
|
|
// FIXME: we have to enable full redraw here because of the
|
|
|
|
// visual box corners that define the inset. If we know for
|
|
|
|
// sure that we stay within the same cell we can optimize for
|
|
|
|
// that using:
|
2010-07-08 20:04:35 +00:00
|
|
|
//cur.screenUpdateFlags(Update::SinglePar | Update::FitCursor);
|
2006-11-21 16:58:45 +00:00
|
|
|
}
|
2004-02-27 09:18:03 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (cur.pos() != 0 && cur.prevAtom()->asSpaceInset()) {
|
|
|
|
cur.prevAtom().nucleus()->asSpaceInset()->incSpace();
|
2006-11-22 14:45:33 +00:00
|
|
|
// FIXME: we have to enable full redraw here because of the
|
|
|
|
// visual box corners that define the inset. If we know for
|
|
|
|
// sure that we stay within the same cell we can optimize for
|
|
|
|
// that using:
|
2010-07-08 20:04:35 +00:00
|
|
|
//cur.screenUpdateFlags(Update::SinglePar | Update::FitCursor);
|
2004-02-27 09:18:03 +00:00
|
|
|
return true;
|
|
|
|
}
|
2006-11-21 16:58:45 +00:00
|
|
|
|
2007-11-05 19:41:16 +00:00
|
|
|
if (cur.popForward()) {
|
2006-11-22 14:45:33 +00:00
|
|
|
// FIXME: we have to enable full redraw here because of the
|
|
|
|
// visual box corners that define the inset. If we know for
|
|
|
|
// sure that we stay within the same cell we can optimize for
|
|
|
|
// that using:
|
2010-07-08 20:04:35 +00:00
|
|
|
//cur.screenUpdateFlags(Update::FitCursor);
|
2004-02-27 09:18:03 +00:00
|
|
|
return true;
|
2006-11-21 16:58:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// if we are at the very end, leave the formula
|
2004-02-27 09:18:03 +00:00
|
|
|
return cur.pos() != cur.lastpos();
|
|
|
|
}
|
|
|
|
|
2008-10-23 00:48:06 +00:00
|
|
|
// These should be treated differently when not in text mode:
|
2011-06-19 16:41:23 +00:00
|
|
|
if (cur.inRegexped()) {
|
|
|
|
switch (c) {
|
|
|
|
case '\\':
|
|
|
|
cur.niceInsert(createInsetMath("backslash", buf));
|
|
|
|
break;
|
|
|
|
case '^':
|
|
|
|
cur.niceInsert(createInsetMath("mathcircumflex", buf));
|
|
|
|
break;
|
|
|
|
case '{':
|
|
|
|
case '}':
|
|
|
|
case '#':
|
|
|
|
case '%':
|
|
|
|
case '_':
|
|
|
|
cur.niceInsert(createInsetMath(docstring(1, c), buf));
|
|
|
|
break;
|
|
|
|
case '~':
|
|
|
|
cur.niceInsert(createInsetMath("sim", buf));
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
cur.insert(c);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
} else if (currentMode() != InsetMath::TEXT_MODE) {
|
2005-05-01 16:15:32 +00:00
|
|
|
if (c == '_') {
|
2006-03-20 14:42:04 +00:00
|
|
|
script(cur, false, save_selection);
|
2005-05-01 16:15:32 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (c == '^') {
|
2006-03-20 14:42:04 +00:00
|
|
|
script(cur, true, save_selection);
|
2005-05-01 16:15:32 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (c == '~') {
|
2009-11-08 11:45:46 +00:00
|
|
|
cur.niceInsert(createInsetMath("sim", buf));
|
2005-05-01 16:15:32 +00:00
|
|
|
return true;
|
|
|
|
}
|
2009-07-03 00:05:58 +00:00
|
|
|
if (currentMode() == InsetMath::MATH_MODE && !isAsciiOrMathAlpha(c)) {
|
2009-11-08 11:45:46 +00:00
|
|
|
MathAtom at = createInsetMath("text", buf);
|
2009-04-05 01:14:10 +00:00
|
|
|
at.nucleus()->cell(0).push_back(MathAtom(new InsetMathChar(c)));
|
|
|
|
cur.niceInsert(at);
|
|
|
|
cur.posForward();
|
|
|
|
return true;
|
|
|
|
}
|
2008-10-23 00:48:06 +00:00
|
|
|
} else {
|
|
|
|
if (c == '^') {
|
2009-11-08 11:45:46 +00:00
|
|
|
cur.niceInsert(createInsetMath("textasciicircum", buf));
|
2008-10-23 00:48:06 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (c == '~') {
|
2009-11-08 11:45:46 +00:00
|
|
|
cur.niceInsert(createInsetMath("textasciitilde", buf));
|
2008-10-23 00:48:06 +00:00
|
|
|
return true;
|
|
|
|
}
|
2004-02-27 09:18:03 +00:00
|
|
|
}
|
|
|
|
|
2006-05-01 08:05:22 +00:00
|
|
|
if (c == '{' || c == '}' || c == '&' || c == '$' || c == '#' ||
|
2008-10-27 23:09:08 +00:00
|
|
|
c == '%' || c == '_') {
|
2009-11-08 11:45:46 +00:00
|
|
|
cur.niceInsert(createInsetMath(docstring(1, c), buf));
|
2004-02-27 09:18:03 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// try auto-correction
|
2009-02-08 01:14:48 +00:00
|
|
|
if (lyxrc.autocorrection_math && cur.autocorrect() && cur.pos() != 0
|
|
|
|
&& math_autocorrect(cur.prevAtom(), c))
|
2008-12-19 10:26:33 +00:00
|
|
|
return true;
|
2004-02-27 09:18:03 +00:00
|
|
|
|
|
|
|
// no special circumstances, so insert the character without any fuss
|
|
|
|
cur.insert(c);
|
2009-01-15 09:48:00 +00:00
|
|
|
if (lyxrc.autocorrection_math) {
|
|
|
|
if (!cur.autocorrect())
|
|
|
|
cur.message(_("Autocorrect Off ('!' to enter)"));
|
|
|
|
else
|
|
|
|
cur.message(_("Autocorrect On (<space> to exit)"));
|
|
|
|
}
|
2004-02-27 09:18:03 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
bool InsetMathNest::interpretString(Cursor & cur, docstring const & str)
|
2006-05-01 08:05:22 +00:00
|
|
|
{
|
2006-09-16 18:11:38 +00:00
|
|
|
// Create a InsetMathBig from cur.cell()[cur.pos() - 1] and t if
|
2006-05-01 08:05:22 +00:00
|
|
|
// possible
|
|
|
|
if (!cur.empty() && cur.pos() > 0 &&
|
|
|
|
cur.cell()[cur.pos() - 1]->asUnknownInset()) {
|
2006-09-16 18:11:38 +00:00
|
|
|
if (InsetMathBig::isBigInsetDelim(str)) {
|
2006-10-22 10:15:23 +00:00
|
|
|
docstring prev = asString(cur.cell()[cur.pos() - 1]);
|
2006-05-01 08:05:22 +00:00
|
|
|
if (prev[0] == '\\') {
|
|
|
|
prev = prev.substr(1);
|
|
|
|
latexkeys const * l = in_word_set(prev);
|
|
|
|
if (l && l->inset == "big") {
|
|
|
|
cur.cell()[cur.pos() - 1] =
|
2006-09-16 18:11:38 +00:00
|
|
|
MathAtom(new InsetMathBig(prev, str));
|
2006-05-01 08:05:22 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-15 00:22:54 +00:00
|
|
|
bool InsetMathNest::script(Cursor & cur, bool up)
|
|
|
|
{
|
2008-03-15 02:42:59 +00:00
|
|
|
return script(cur, up, docstring());
|
2008-03-15 00:22:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-05-28 22:27:45 +00:00
|
|
|
bool InsetMathNest::script(Cursor & cur, bool up,
|
2006-10-22 10:15:23 +00:00
|
|
|
docstring const & save_selection)
|
2004-02-27 09:18:03 +00:00
|
|
|
{
|
2004-08-12 21:48:21 +00:00
|
|
|
// Hack to get \^ and \_ working
|
2006-08-08 21:55:41 +00:00
|
|
|
//lyxerr << "handling script: up: " << up << endl;
|
2004-02-27 09:18:03 +00:00
|
|
|
if (cur.inMacroMode() && cur.macroName() == "\\") {
|
|
|
|
if (up)
|
2009-11-08 11:45:46 +00:00
|
|
|
cur.niceInsert(createInsetMath("mathcircumflex", cur.buffer()));
|
2004-02-27 09:18:03 +00:00
|
|
|
else
|
2006-10-19 16:38:13 +00:00
|
|
|
interpretChar(cur, '_');
|
2004-02-27 09:18:03 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
cur.macroModeClose();
|
2004-03-25 09:16:36 +00:00
|
|
|
if (asScriptInset() && cur.idx() == 0) {
|
2004-02-27 09:18:03 +00:00
|
|
|
// we are in a nucleus of a script inset, move to _our_ script
|
2006-09-16 18:11:38 +00:00
|
|
|
InsetMathScript * inset = asScriptInset();
|
2006-08-08 21:55:41 +00:00
|
|
|
//lyxerr << " going to cell " << inset->idxOfScript(up) << endl;
|
2004-03-25 09:16:36 +00:00
|
|
|
inset->ensure(up);
|
|
|
|
cur.idx() = inset->idxOfScript(up);
|
2004-02-27 09:18:03 +00:00
|
|
|
cur.pos() = 0;
|
|
|
|
} else if (cur.pos() != 0 && cur.prevAtom()->asScriptInset()) {
|
|
|
|
--cur.pos();
|
2006-09-16 18:11:38 +00:00
|
|
|
InsetMathScript * inset = cur.nextAtom().nucleus()->asScriptInset();
|
2004-03-25 09:16:36 +00:00
|
|
|
cur.push(*inset);
|
2005-12-02 06:34:19 +00:00
|
|
|
inset->ensure(up);
|
2004-03-25 09:16:36 +00:00
|
|
|
cur.idx() = inset->idxOfScript(up);
|
2004-02-27 09:18:03 +00:00
|
|
|
cur.pos() = cur.lastpos();
|
|
|
|
} else {
|
2004-03-25 09:16:36 +00:00
|
|
|
// convert the thing to our left to a scriptinset or create a new
|
|
|
|
// one if in the very first position of the array
|
|
|
|
if (cur.pos() == 0) {
|
2005-07-15 08:51:34 +00:00
|
|
|
//lyxerr << "new scriptinset" << endl;
|
2009-11-08 11:45:46 +00:00
|
|
|
cur.insert(new InsetMathScript(buffer_, up));
|
2004-03-25 09:16:36 +00:00
|
|
|
} else {
|
2005-07-15 08:51:34 +00:00
|
|
|
//lyxerr << "converting prev atom " << endl;
|
2009-11-08 11:45:46 +00:00
|
|
|
cur.prevAtom() = MathAtom(new InsetMathScript(buffer_, cur.prevAtom(), up));
|
2004-03-25 09:16:36 +00:00
|
|
|
}
|
2004-04-05 16:31:52 +00:00
|
|
|
--cur.pos();
|
2006-09-16 18:11:38 +00:00
|
|
|
InsetMathScript * inset = cur.nextAtom().nucleus()->asScriptInset();
|
2007-04-25 03:01:35 +00:00
|
|
|
// See comment in MathParser.cpp for special handling of {}-bases
|
2006-09-09 15:27:44 +00:00
|
|
|
|
2004-03-25 09:16:36 +00:00
|
|
|
cur.push(*inset);
|
|
|
|
cur.idx() = 1;
|
2004-02-27 09:18:03 +00:00
|
|
|
cur.pos() = 0;
|
|
|
|
}
|
2006-03-20 14:42:04 +00:00
|
|
|
//lyxerr << "inserting selection 1:\n" << save_selection << endl;
|
|
|
|
cur.niceInsert(save_selection);
|
2004-04-05 16:31:52 +00:00
|
|
|
cur.resetAnchor();
|
2006-03-20 14:42:04 +00:00
|
|
|
//lyxerr << "inserting selection 2:\n" << save_selection << endl;
|
2004-02-27 09:18:03 +00:00
|
|
|
return true;
|
|
|
|
}
|
2006-10-21 00:16:43 +00:00
|
|
|
|
|
|
|
|
2008-02-21 19:42:34 +00:00
|
|
|
bool InsetMathNest::completionSupported(Cursor const & cur) const
|
|
|
|
{
|
|
|
|
return cur.inMacroMode();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool InsetMathNest::inlineCompletionSupported(Cursor const & cur) const
|
|
|
|
{
|
|
|
|
return cur.inMacroMode();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool InsetMathNest::automaticInlineCompletion() const
|
|
|
|
{
|
|
|
|
return lyxrc.completion_inline_math;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool InsetMathNest::automaticPopupCompletion() const
|
|
|
|
{
|
|
|
|
return lyxrc.completion_popup_math;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-15 00:22:54 +00:00
|
|
|
CompletionList const *
|
2008-02-22 21:11:19 +00:00
|
|
|
InsetMathNest::createCompletionList(Cursor const & cur) const
|
2008-02-21 19:42:34 +00:00
|
|
|
{
|
|
|
|
if (!cur.inMacroMode())
|
2008-02-21 23:36:02 +00:00
|
|
|
return 0;
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2008-02-21 23:36:02 +00:00
|
|
|
return new MathCompletionList(cur);
|
2008-02-21 19:42:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
docstring InsetMathNest::completionPrefix(Cursor const & cur) const
|
|
|
|
{
|
|
|
|
if (!cur.inMacroMode())
|
|
|
|
return docstring();
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2008-02-21 19:42:34 +00:00
|
|
|
return cur.activeMacro()->name();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool InsetMathNest::insertCompletion(Cursor & cur, docstring const & s,
|
|
|
|
bool finished)
|
|
|
|
{
|
|
|
|
if (!cur.inMacroMode())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// append completion to active macro
|
|
|
|
InsetMathUnknown * inset = cur.activeMacro();
|
|
|
|
inset->setName(inset->name() + s);
|
|
|
|
|
|
|
|
// finish macro
|
|
|
|
if (finished) {
|
|
|
|
#if 0
|
|
|
|
// FIXME: this creates duplicates in the completion popup
|
|
|
|
// which looks ugly. Moreover the changes the list lengths
|
|
|
|
// which seems to
|
|
|
|
confuse the popup as well.
|
|
|
|
MathCompletionList::addToFavorites(inset->name());
|
|
|
|
#endif
|
|
|
|
lyx::dispatch(FuncRequest(LFUN_SELF_INSERT, " "));
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-10-13 11:25:37 +00:00
|
|
|
void InsetMathNest::completionPosAndDim(Cursor const & cur, int & x, int & y,
|
2008-02-21 19:42:34 +00:00
|
|
|
Dimension & dim) const
|
|
|
|
{
|
|
|
|
Inset const * inset = cur.activeMacro();
|
|
|
|
if (!inset)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// get inset dimensions
|
|
|
|
dim = cur.bv().coordCache().insets().dim(inset);
|
2008-02-21 19:45:05 +00:00
|
|
|
// FIXME: these 3 are no accurate, but should depend on the font.
|
|
|
|
// Now the popup jumps down if you enter a char with descent > 0.
|
|
|
|
dim.des += 3;
|
|
|
|
dim.asc += 3;
|
|
|
|
|
|
|
|
// and position
|
2010-03-10 16:57:01 +00:00
|
|
|
Point xy = cur.bv().coordCache().insets().xy(inset);
|
2008-02-21 19:42:34 +00:00
|
|
|
x = xy.x_;
|
|
|
|
y = xy.y_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-10 19:57:00 +00:00
|
|
|
bool InsetMathNest::cursorMathForward(Cursor & cur)
|
|
|
|
{
|
|
|
|
if (cur.pos() != cur.lastpos() && cur.openable(cur.nextAtom())) {
|
|
|
|
cur.pushBackward(*cur.nextAtom().nucleus());
|
|
|
|
cur.inset().idxFirst(cur);
|
|
|
|
return true;
|
2008-10-13 11:25:37 +00:00
|
|
|
}
|
2008-04-06 20:11:05 +00:00
|
|
|
if (cur.posForward() || idxForward(cur))
|
2008-02-10 19:57:00 +00:00
|
|
|
return true;
|
|
|
|
// try to pop forwards --- but don't pop out of math! leave that to
|
|
|
|
// the FINISH lfuns
|
|
|
|
int s = cur.depth() - 2;
|
|
|
|
if (s >= 0 && cur[s].inset().asInsetMath())
|
|
|
|
return cur.popForward();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool InsetMathNest::cursorMathBackward(Cursor & cur)
|
|
|
|
{
|
|
|
|
if (cur.pos() != 0 && cur.openable(cur.prevAtom())) {
|
|
|
|
cur.posBackward();
|
|
|
|
cur.push(*cur.nextAtom().nucleus());
|
|
|
|
cur.inset().idxLast(cur);
|
|
|
|
return true;
|
2008-10-13 11:25:37 +00:00
|
|
|
}
|
2008-04-06 20:11:05 +00:00
|
|
|
if (cur.posBackward() || idxBackward(cur))
|
2008-02-10 19:57:00 +00:00
|
|
|
return true;
|
2008-10-13 11:25:37 +00:00
|
|
|
// try to pop backwards --- but don't pop out of math! leave that to
|
2008-02-10 19:57:00 +00:00
|
|
|
// the FINISH lfuns
|
2009-07-08 01:41:06 +00:00
|
|
|
int s = cur.depth() - 2;
|
2008-02-10 19:57:00 +00:00
|
|
|
if (s >= 0 && cur[s].inset().asInsetMath())
|
|
|
|
return cur.popBackward();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-21 19:42:34 +00:00
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
MathCompletionList::MathCompletionList(Cursor const & cur)
|
|
|
|
{
|
|
|
|
// fill it with macros from the buffer
|
2008-02-23 18:11:35 +00:00
|
|
|
MacroNameSet macros;
|
2008-11-17 11:46:07 +00:00
|
|
|
cur.buffer()->listMacroNames(macros);
|
2008-02-23 18:11:35 +00:00
|
|
|
MacroNameSet::const_iterator it;
|
2008-02-21 19:42:34 +00:00
|
|
|
for (it = macros.begin(); it != macros.end(); ++it) {
|
2008-11-17 11:46:07 +00:00
|
|
|
if (cur.buffer()->getMacro(*it, cur, false))
|
2008-02-21 19:42:34 +00:00
|
|
|
locals.push_back("\\" + *it);
|
|
|
|
}
|
|
|
|
sort(locals.begin(), locals.end());
|
|
|
|
|
2012-05-28 20:41:32 +00:00
|
|
|
if (!globals.empty())
|
2008-02-21 19:42:34 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
// fill in global macros
|
|
|
|
macros.clear();
|
|
|
|
MacroTable::globalMacros().getMacroNames(macros);
|
2008-08-02 14:11:04 +00:00
|
|
|
//lyxerr << "Globals completion macros: ";
|
2008-02-21 19:42:34 +00:00
|
|
|
for (it = macros.begin(); it != macros.end(); ++it) {
|
2008-08-02 14:11:04 +00:00
|
|
|
//lyxerr << "\\" + *it << " ";
|
2008-02-21 19:42:34 +00:00
|
|
|
globals.push_back("\\" + *it);
|
|
|
|
}
|
2008-08-02 14:11:04 +00:00
|
|
|
//lyxerr << std::endl;
|
2008-02-21 19:42:34 +00:00
|
|
|
|
|
|
|
// fill in global commands
|
|
|
|
globals.push_back(from_ascii("\\boxed"));
|
|
|
|
globals.push_back(from_ascii("\\fbox"));
|
|
|
|
globals.push_back(from_ascii("\\framebox"));
|
|
|
|
globals.push_back(from_ascii("\\makebox"));
|
|
|
|
globals.push_back(from_ascii("\\kern"));
|
2014-08-24 22:44:09 +00:00
|
|
|
globals.push_back(from_ascii("\\xhookrightarrow"));
|
|
|
|
globals.push_back(from_ascii("\\xhookleftarrow"));
|
2008-02-21 19:42:34 +00:00
|
|
|
globals.push_back(from_ascii("\\xrightarrow"));
|
2014-08-24 22:44:09 +00:00
|
|
|
globals.push_back(from_ascii("\\xRightarrow"));
|
|
|
|
globals.push_back(from_ascii("\\xrightharpoondown"));
|
|
|
|
globals.push_back(from_ascii("\\xrightharpoonup"));
|
|
|
|
globals.push_back(from_ascii("\\xrightleftharpoons"));
|
2008-02-21 19:42:34 +00:00
|
|
|
globals.push_back(from_ascii("\\xleftarrow"));
|
2014-08-24 22:44:09 +00:00
|
|
|
globals.push_back(from_ascii("\\xLeftarrow"));
|
|
|
|
globals.push_back(from_ascii("\\xleftharpoondown"));
|
|
|
|
globals.push_back(from_ascii("\\xleftharpoonup"));
|
|
|
|
globals.push_back(from_ascii("\\xleftrightarrow"));
|
|
|
|
globals.push_back(from_ascii("\\xLeftrightarrow"));
|
|
|
|
globals.push_back(from_ascii("\\xleftrightharpoons"));
|
|
|
|
globals.push_back(from_ascii("\\xmapsto"));
|
2008-02-21 19:42:34 +00:00
|
|
|
globals.push_back(from_ascii("\\split"));
|
|
|
|
globals.push_back(from_ascii("\\gathered"));
|
|
|
|
globals.push_back(from_ascii("\\aligned"));
|
|
|
|
globals.push_back(from_ascii("\\alignedat"));
|
|
|
|
globals.push_back(from_ascii("\\cases"));
|
|
|
|
globals.push_back(from_ascii("\\substack"));
|
2008-08-06 18:44:35 +00:00
|
|
|
globals.push_back(from_ascii("\\xymatrix"));
|
2010-09-19 22:12:06 +00:00
|
|
|
globals.push_back(from_ascii("\\Diagram"));
|
2008-02-21 19:42:34 +00:00
|
|
|
globals.push_back(from_ascii("\\subarray"));
|
|
|
|
globals.push_back(from_ascii("\\array"));
|
|
|
|
globals.push_back(from_ascii("\\sqrt"));
|
|
|
|
globals.push_back(from_ascii("\\root"));
|
|
|
|
globals.push_back(from_ascii("\\tabular"));
|
|
|
|
globals.push_back(from_ascii("\\stackrel"));
|
2012-12-28 18:51:28 +00:00
|
|
|
globals.push_back(from_ascii("\\stackrelthree"));
|
2008-02-21 19:42:34 +00:00
|
|
|
globals.push_back(from_ascii("\\binom"));
|
|
|
|
globals.push_back(from_ascii("\\choose"));
|
2008-03-31 01:23:25 +00:00
|
|
|
globals.push_back(from_ascii("\\brace"));
|
|
|
|
globals.push_back(from_ascii("\\brack"));
|
2008-02-21 19:42:34 +00:00
|
|
|
globals.push_back(from_ascii("\\frac"));
|
|
|
|
globals.push_back(from_ascii("\\over"));
|
|
|
|
globals.push_back(from_ascii("\\nicefrac"));
|
|
|
|
globals.push_back(from_ascii("\\unitfrac"));
|
|
|
|
globals.push_back(from_ascii("\\unitfracthree"));
|
|
|
|
globals.push_back(from_ascii("\\unitone"));
|
|
|
|
globals.push_back(from_ascii("\\unittwo"));
|
|
|
|
globals.push_back(from_ascii("\\infer"));
|
|
|
|
globals.push_back(from_ascii("\\atop"));
|
|
|
|
globals.push_back(from_ascii("\\lefteqn"));
|
|
|
|
globals.push_back(from_ascii("\\boldsymbol"));
|
2008-03-06 20:49:59 +00:00
|
|
|
globals.push_back(from_ascii("\\bm"));
|
2008-02-21 19:42:34 +00:00
|
|
|
globals.push_back(from_ascii("\\color"));
|
|
|
|
globals.push_back(from_ascii("\\normalcolor"));
|
|
|
|
globals.push_back(from_ascii("\\textcolor"));
|
2009-02-28 02:43:26 +00:00
|
|
|
globals.push_back(from_ascii("\\cfrac"));
|
2009-04-07 00:23:38 +00:00
|
|
|
globals.push_back(from_ascii("\\cfracleft"));
|
|
|
|
globals.push_back(from_ascii("\\cfracright"));
|
2008-02-21 19:42:34 +00:00
|
|
|
globals.push_back(from_ascii("\\dfrac"));
|
|
|
|
globals.push_back(from_ascii("\\tfrac"));
|
|
|
|
globals.push_back(from_ascii("\\dbinom"));
|
|
|
|
globals.push_back(from_ascii("\\tbinom"));
|
|
|
|
globals.push_back(from_ascii("\\hphantom"));
|
|
|
|
globals.push_back(from_ascii("\\phantom"));
|
|
|
|
globals.push_back(from_ascii("\\vphantom"));
|
2012-01-23 01:49:49 +00:00
|
|
|
globals.push_back(from_ascii("\\cancel"));
|
|
|
|
globals.push_back(from_ascii("\\bcancel"));
|
|
|
|
globals.push_back(from_ascii("\\xcancel"));
|
|
|
|
globals.push_back(from_ascii("\\cancelto"));
|
2012-01-08 12:34:12 +00:00
|
|
|
globals.push_back(from_ascii("\\smash"));
|
|
|
|
globals.push_back(from_ascii("\\mathclap"));
|
|
|
|
globals.push_back(from_ascii("\\mathllap"));
|
|
|
|
globals.push_back(from_ascii("\\mathrlap"));
|
2008-02-23 18:11:35 +00:00
|
|
|
MathWordList const & words = mathedWordList();
|
|
|
|
MathWordList::const_iterator it2;
|
2008-08-02 14:11:04 +00:00
|
|
|
//lyxerr << "Globals completion commands: ";
|
2008-02-21 19:42:34 +00:00
|
|
|
for (it2 = words.begin(); it2 != words.end(); ++it2) {
|
2014-12-29 20:13:42 +00:00
|
|
|
if (it2->second.inset != "macro") {
|
|
|
|
// macros are already read from MacroTable::globalMacros()
|
|
|
|
globals.push_back('\\' + it2->first);
|
|
|
|
//lyxerr << '\\' + it2->first << ' ';
|
|
|
|
}
|
2008-02-21 19:42:34 +00:00
|
|
|
}
|
2008-08-02 14:11:04 +00:00
|
|
|
//lyxerr << std::endl;
|
2008-02-21 19:42:34 +00:00
|
|
|
sort(globals.begin(), globals.end());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MathCompletionList::~MathCompletionList()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
size_type MathCompletionList::size() const
|
|
|
|
{
|
2008-02-21 23:36:02 +00:00
|
|
|
return locals.size() + globals.size();
|
2008-02-21 19:42:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-25 14:25:49 +00:00
|
|
|
docstring const & MathCompletionList::data(size_t idx) const
|
2008-02-21 19:42:34 +00:00
|
|
|
{
|
|
|
|
size_t lsize = locals.size();
|
2008-02-21 23:36:02 +00:00
|
|
|
if (idx >= lsize)
|
|
|
|
return globals[idx - lsize];
|
2008-02-21 19:42:34 +00:00
|
|
|
else
|
2008-02-21 23:36:02 +00:00
|
|
|
return locals[idx];
|
2008-02-21 19:42:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-10-13 11:25:37 +00:00
|
|
|
std::string MathCompletionList::icon(size_t idx) const
|
2008-02-21 19:42:34 +00:00
|
|
|
{
|
|
|
|
// get the latex command
|
|
|
|
docstring cmd;
|
|
|
|
size_t lsize = locals.size();
|
2008-02-21 23:36:02 +00:00
|
|
|
if (idx >= lsize)
|
|
|
|
cmd = globals[idx - lsize];
|
2008-02-21 19:42:34 +00:00
|
|
|
else
|
2008-02-21 23:36:02 +00:00
|
|
|
cmd = locals[idx];
|
2008-10-13 11:25:37 +00:00
|
|
|
|
2008-02-21 19:42:34 +00:00
|
|
|
// get the icon resource name by stripping the backslash
|
2015-02-14 19:32:25 +00:00
|
|
|
docstring icon_name = frontend::Application::mathIcon(cmd.substr(1));
|
|
|
|
if (icon_name.empty())
|
|
|
|
return std::string();
|
|
|
|
return "images/math/" + to_utf8(icon_name);
|
2008-02-21 19:42:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<docstring> MathCompletionList::globals;
|
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
} // namespace lyx
|