mirror of
https://git.lyx.org/repos/lyx.git
synced 2025-01-21 23:09:40 +00:00
redo undo
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8481 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
b1fa5cd0d0
commit
4c8d536692
@ -607,6 +607,7 @@ void BufferView::Pimpl::update()
|
||||
updateScrollbar();
|
||||
}
|
||||
screen().redraw(*bv_);
|
||||
bv_->owner()->view_state_changed();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
|
||||
2004-03-08 André Pönitz <poenitz@gmx.net>
|
||||
|
||||
* undo.[Ch]: use 'StableDocumentIterator' as base for
|
||||
the Undo struct.
|
||||
|
||||
2004-03-07 Jürgen Spitzmüller <j.spitzmueller@gmx.de>
|
||||
|
||||
* LaTeXFeatures.C:
|
||||
|
34
src/cursor.C
34
src/cursor.C
@ -85,7 +85,7 @@ void LCursor::setCursor(DocumentIterator const & cur, bool sel)
|
||||
|
||||
DispatchResult LCursor::dispatch(FuncRequest const & cmd0)
|
||||
{
|
||||
lyxerr << "\nLCursor::dispatch: cmd: " << cmd0 << endl << *this << endl;
|
||||
//lyxerr << "\nLCursor::dispatch: cmd: " << cmd0 << endl << *this << endl;
|
||||
BOOST_ASSERT(pos() <= lastpos());
|
||||
BOOST_ASSERT(idx() <= lastidx());
|
||||
BOOST_ASSERT(par() <= lastpar());
|
||||
@ -1235,38 +1235,6 @@ CursorSlice LCursor::normalAnchor()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
DispatchResult dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
{
|
||||
// mouse clicks are somewhat special
|
||||
// check
|
||||
switch (cmd.action) {
|
||||
case LFUN_MOUSE_PRESS:
|
||||
case LFUN_MOUSE_MOTION:
|
||||
case LFUN_MOUSE_RELEASE:
|
||||
case LFUN_MOUSE_DOUBLE: {
|
||||
CursorSlice & pos = back();
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
getPos(x, y);
|
||||
if (x < cmd.x && pos() != 0) {
|
||||
DispatchResult const res = prevAtom().nucleus()->dispatch(cmd);
|
||||
if (res.dispatched())
|
||||
return res;
|
||||
}
|
||||
if (x > cmd.x && pos() != lastpos()) {
|
||||
DispatchResult const res = inset()->dispatch(cmd);
|
||||
if (res.dispatched())
|
||||
return res;
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
void LCursor::handleFont(string const & font)
|
||||
{
|
||||
lyxerr << "LCursor::handleFont: " << font << endl;
|
||||
|
@ -30,9 +30,7 @@ class MathUnknownInset;
|
||||
class MathGridInset;
|
||||
|
||||
|
||||
/**
|
||||
* The cursor class describes the position of a cursor within a document.
|
||||
*/
|
||||
/// The cursor class describes the position of a cursor within a document.
|
||||
|
||||
// The public inheritance should go in favour of a suitable data member
|
||||
// (or maybe private inheritance) at some point of time.
|
||||
|
@ -14,9 +14,6 @@
|
||||
|
||||
|
||||
|
||||
std::ostream & operator<<(std::ostream & os, DocumentIterator const & cur);
|
||||
|
||||
|
||||
DocumentIterator::DocumentIterator()
|
||||
: bv_(0)
|
||||
{}
|
||||
@ -393,9 +390,49 @@ DocumentIterator insetEnd()
|
||||
}
|
||||
|
||||
|
||||
std::ostream & operator<<(std::ostream & os, DocumentIterator const & cur)
|
||||
std::ostream & operator<<(std::ostream & os, DocumentIterator const & dit)
|
||||
{
|
||||
for (size_t i = 0, n = cur.size(); i != n; ++i)
|
||||
os << " " << cur.operator[](i) << "\n";
|
||||
os << "bv: " << &dit.bv() << "\n";
|
||||
for (size_t i = 0, n = dit.size(); i != n; ++i)
|
||||
os << " " << dit.operator[](i) << "\n";
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
StableDocumentIterator::StableDocumentIterator(const DocumentIterator & dit)
|
||||
{
|
||||
data_ = dit;
|
||||
for (size_t i = 0, n = data_.size(); i != n; ++i)
|
||||
data_[i].inset_ = 0;
|
||||
}
|
||||
|
||||
|
||||
DocumentIterator
|
||||
StableDocumentIterator::asDocumentIterator(BufferView & bv) const
|
||||
{
|
||||
// this function re-creates the cache of inset pointers
|
||||
//lyxerr << "converting:\n" << *this << std::endl;
|
||||
DocumentIterator dit(bv);
|
||||
dit.clear();
|
||||
InsetBase * inset = 0;
|
||||
for (size_t i = 0, n = data_.size(); i != n; ++i) {
|
||||
dit.push_back(data_[i]);
|
||||
dit.back().inset_ = inset;
|
||||
if (i + 1 != n)
|
||||
inset = dit.nextInset();
|
||||
}
|
||||
//lyxerr << "convert:\n" << *this << " to:\n" << dit << std::endl;
|
||||
return dit;
|
||||
}
|
||||
|
||||
|
||||
std::ostream & operator<<(std::ostream & os, StableDocumentIterator const & dit)
|
||||
{
|
||||
for (size_t i = 0, n = dit.data_.size(); i != n; ++i)
|
||||
os << " " << dit.data_[i] << "\n";
|
||||
return os;
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "cursor_slice.h"
|
||||
|
||||
#include <vector>
|
||||
#include <iosfwd>
|
||||
|
||||
class BufferView;
|
||||
class MathAtom;
|
||||
@ -23,6 +24,7 @@ class Paragraph;
|
||||
class Row;
|
||||
|
||||
|
||||
|
||||
// only needed for gcc 2.95, remove when support terminated
|
||||
template <typename A, typename B>
|
||||
bool ptr_cmp(A const * a, B const * b)
|
||||
@ -166,6 +168,9 @@ public:
|
||||
void forwardIdx();
|
||||
/// move on one inset
|
||||
void forwardInset();
|
||||
/// output
|
||||
friend std::ostream &
|
||||
operator<<(std::ostream & os, DocumentIterator const & cur);
|
||||
|
||||
private:
|
||||
///
|
||||
@ -182,4 +187,31 @@ DocumentIterator insetBegin(BufferView & bv, InsetBase * inset);
|
||||
///
|
||||
DocumentIterator insetEnd();
|
||||
|
||||
|
||||
// The difference to a ('non stable') DocumentIterator is the removed
|
||||
// (overwritte by 0...) part of the CursorSlice data items. So this thing
|
||||
// is suitable for external storage, but not for iteration as such.
|
||||
|
||||
class StableDocumentIterator {
|
||||
public:
|
||||
///
|
||||
StableDocumentIterator() {}
|
||||
/// non-explicit intended
|
||||
StableDocumentIterator(const DocumentIterator & it);
|
||||
///
|
||||
DocumentIterator asDocumentIterator(BufferView & bv) const;
|
||||
///
|
||||
size_t size() const { return data_.size(); }
|
||||
///
|
||||
friend std::ostream &
|
||||
operator<<(std::ostream & os, StableDocumentIterator const & cur);
|
||||
///
|
||||
friend std::istream &
|
||||
operator>>(std::istream & is, StableDocumentIterator & cur);
|
||||
private:
|
||||
std::vector<CursorSlice> data_;
|
||||
};
|
||||
|
||||
bool operator==(StableDocumentIterator const &, StableDocumentIterator const &);
|
||||
|
||||
#endif
|
||||
|
@ -272,7 +272,7 @@ bool InsetCollapsable::hitButton(FuncRequest const & cmd) const
|
||||
|
||||
string const InsetCollapsable::getNewLabel(string const & l) const
|
||||
{
|
||||
string la;
|
||||
string label;
|
||||
pos_type const max_length = 15;
|
||||
pos_type const p_siz = inset.paragraphs().begin()->size();
|
||||
pos_type const n = min(max_length, p_siz);
|
||||
@ -281,13 +281,13 @@ string const InsetCollapsable::getNewLabel(string const & l) const
|
||||
for( ; i < n && j < p_siz; ++j) {
|
||||
if (inset.paragraphs().begin()->isInset(j))
|
||||
continue;
|
||||
la += inset.paragraphs().begin()->getChar(j);
|
||||
label += inset.paragraphs().begin()->getChar(j);
|
||||
++i;
|
||||
}
|
||||
if (inset.paragraphs().size() > 1 || (i > 0 && j < p_siz)) {
|
||||
la += "...";
|
||||
label += "...";
|
||||
}
|
||||
return la.empty() ? l : la;
|
||||
return label.empty() ? l : label;
|
||||
}
|
||||
|
||||
|
||||
|
@ -820,7 +820,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose)
|
||||
kb_action action = cmd.action;
|
||||
|
||||
lyxerr[Debug::ACTION] << "LyXFunc::dispatch: cmd: " << cmd << endl;
|
||||
lyxerr << "LyXFunc::dispatch: cmd: " << cmd << endl;
|
||||
//lyxerr << "LyXFunc::dispatch: cmd: " << cmd << endl;
|
||||
|
||||
// we have not done anything wrong yet.
|
||||
errorstat = false;
|
||||
|
@ -307,7 +307,7 @@ void MathNestInset::handleFont
|
||||
{
|
||||
// this whole function is a hack and won't work for incremental font
|
||||
// changes...
|
||||
//recordUndo(cur, Undo::ATOMIC);
|
||||
recordUndo(cur, Undo::ATOMIC);
|
||||
|
||||
if (cur.inset()->asMathInset()->name() == font)
|
||||
cur.handleFont(font);
|
||||
@ -320,7 +320,7 @@ void MathNestInset::handleFont
|
||||
|
||||
void MathNestInset::handleFont2(LCursor & cur, string const & arg)
|
||||
{
|
||||
//recordUndo(cur, Undo::ATOMIC);
|
||||
recordUndo(cur, Undo::ATOMIC);
|
||||
LyXFont font;
|
||||
bool b;
|
||||
bv_funcs::string2font(arg, font, b);
|
||||
@ -354,7 +354,7 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
is >> n;
|
||||
if (was_macro)
|
||||
cur.macroModeClose();
|
||||
//recordUndo(cur, Undo::ATOMIC);
|
||||
recordUndo(cur, Undo::ATOMIC);
|
||||
cur.selPaste(n);
|
||||
break;
|
||||
}
|
||||
@ -531,13 +531,13 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
|
||||
case LFUN_DELETE_WORD_BACKWARD:
|
||||
case LFUN_BACKSPACE:
|
||||
//recordUndo(cur, Undo::ATOMIC);
|
||||
recordUndo(cur, Undo::ATOMIC);
|
||||
cur.backspace();
|
||||
break;
|
||||
|
||||
case LFUN_DELETE_WORD_FORWARD:
|
||||
case LFUN_DELETE:
|
||||
//recordUndo(cur, Undo::ATOMIC);
|
||||
recordUndo(cur, Undo::ATOMIC);
|
||||
cur.erase();
|
||||
cur.dispatched(FINISHED_LEFT);
|
||||
break;
|
||||
@ -566,7 +566,7 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
cur.dispatched(FINISHED_RIGHT);
|
||||
break;
|
||||
}
|
||||
//recordUndo(cur, Undo::ATOMIC);
|
||||
recordUndo(cur, Undo::ATOMIC);
|
||||
if (cmd.argument.size() != 1) {
|
||||
cur.insert(cmd.argument);
|
||||
break;
|
||||
@ -604,7 +604,7 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
}
|
||||
|
||||
case LFUN_CUT:
|
||||
//recordUndo(cur, Undo::DELETE);
|
||||
recordUndo(cur, Undo::DELETE);
|
||||
cur.selCut();
|
||||
break;
|
||||
|
||||
@ -618,7 +618,7 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
if (cmd.argument.empty()) {
|
||||
// do superscript if LyX handles
|
||||
// deadkeys
|
||||
//recordUndo(cur, Undo::ATOMIC);
|
||||
recordUndo(cur, Undo::ATOMIC);
|
||||
script(cur, true);
|
||||
}
|
||||
break;
|
||||
@ -695,14 +695,14 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
case LFUN_MATH_SIZE:
|
||||
#if 0
|
||||
if (!arg.empty()) {
|
||||
//recordUndo(cur, Undo::ATOMIC);
|
||||
recordUndo(cur, Undo::ATOMIC);
|
||||
cur.setSize(arg);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case LFUN_INSERT_MATRIX: {
|
||||
//recordUndo(cur, Undo::ATOMIC);
|
||||
recordUndo(cur, Undo::ATOMIC);
|
||||
unsigned int m = 1;
|
||||
unsigned int n = 1;
|
||||
string v_align;
|
||||
@ -728,14 +728,14 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
ls = '(';
|
||||
if (rs.empty())
|
||||
rs = ')';
|
||||
//recordUndo(cur, Undo::ATOMIC);
|
||||
recordUndo(cur, Undo::ATOMIC);
|
||||
cur.handleNest(MathAtom(new MathDelimInset(ls, rs)));
|
||||
break;
|
||||
}
|
||||
|
||||
case LFUN_SPACE_INSERT:
|
||||
case LFUN_MATH_SPACE:
|
||||
//recordUndo(cur, Undo::ATOMIC);
|
||||
recordUndo(cur, Undo::ATOMIC);
|
||||
cur.insert(MathAtom(new MathSpaceInset(",")));
|
||||
break;
|
||||
|
||||
@ -746,7 +746,7 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
|
||||
case LFUN_INSET_ERT:
|
||||
// interpret this as if a backslash was typed
|
||||
//recordUndo(cur, Undo::ATOMIC);
|
||||
recordUndo(cur, Undo::ATOMIC);
|
||||
interpret(cur, '\\');
|
||||
break;
|
||||
|
||||
@ -754,7 +754,7 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
// handling such that "self-insert" works on "arbitrary stuff" too, and
|
||||
// math-insert only handles special math things like "matrix".
|
||||
case LFUN_INSERT_MATH:
|
||||
//recordUndo(cur, Undo::ATOMIC);
|
||||
recordUndo(cur, Undo::ATOMIC);
|
||||
cur.niceInsert(cmd.argument);
|
||||
break;
|
||||
|
||||
|
@ -898,6 +898,8 @@ void LyXText::redoParagraph(LCursor & cur)
|
||||
void LyXText::insertChar(LCursor & cur, char c)
|
||||
{
|
||||
BOOST_ASSERT(this == cur.text());
|
||||
BOOST_ASSERT(c != Paragraph::META_INSET);
|
||||
|
||||
recordUndo(cur, Undo::INSERT);
|
||||
|
||||
Paragraph & par = cur.paragraph();
|
||||
@ -983,10 +985,7 @@ void LyXText::insertChar(LCursor & cur, char c)
|
||||
}
|
||||
}
|
||||
|
||||
// Here case LyXText::InsertInset already inserted the character
|
||||
if (c != Paragraph::META_INSET)
|
||||
par.insertChar(cur.pos(), c);
|
||||
|
||||
par.insertChar(cur.pos(), c);
|
||||
setCharFont(pit, cur.pos(), rawtmpfont);
|
||||
|
||||
current_font = rawtmpfont;
|
||||
|
23
src/text2.C
23
src/text2.C
@ -72,7 +72,7 @@ using std::string;
|
||||
|
||||
|
||||
LyXText::LyXText(BufferView * bv, bool in_inset)
|
||||
: height_(0), width_(0), maxwidth_(bv ? bv->workWidth() : 100),
|
||||
: width_(0), maxwidth_(bv ? bv->workWidth() : 100), height_(0),
|
||||
background_color_(LColor::background),
|
||||
bv_owner(bv), in_inset_(in_inset), xo_(0), yo_(0)
|
||||
{}
|
||||
@ -865,19 +865,9 @@ void LyXText::updateCounters()
|
||||
void LyXText::insertInset(LCursor & cur, InsetBase * inset)
|
||||
{
|
||||
BOOST_ASSERT(this == cur.text());
|
||||
recordUndo(cur);
|
||||
freezeUndo();
|
||||
BOOST_ASSERT(inset);
|
||||
cur.paragraph().insertInset(cur.pos(), inset);
|
||||
// Just to rebreak and refresh correctly.
|
||||
// The character will not be inserted a second time
|
||||
insertChar(cur, Paragraph::META_INSET);
|
||||
// If we enter a highly editable inset the cursor should be before
|
||||
// the inset. After an undo LyX tries to call inset->edit(...)
|
||||
// and fails if the cursor is behind the inset and getInset
|
||||
// does not return the inset!
|
||||
if (isHighlyEditableInset(inset))
|
||||
cursorLeft(cur);
|
||||
unFreezeUndo();
|
||||
redoParagraph(cur);
|
||||
}
|
||||
|
||||
|
||||
@ -1014,7 +1004,6 @@ void LyXText::setSelectionRange(LCursor & cur, lyx::pos_type length)
|
||||
void LyXText::replaceSelectionWithString(LCursor & cur, string const & str)
|
||||
{
|
||||
recordUndo(cur);
|
||||
freezeUndo();
|
||||
|
||||
// Get font setting before we cut
|
||||
pos_type pos = cur.selEnd().pos();
|
||||
@ -1032,7 +1021,6 @@ void LyXText::replaceSelectionWithString(LCursor & cur, string const & str)
|
||||
|
||||
// Cut the selection
|
||||
cutSelection(cur, true, false);
|
||||
unFreezeUndo();
|
||||
}
|
||||
|
||||
|
||||
@ -1124,7 +1112,10 @@ void LyXText::setCursor(CursorSlice & cur, par_type par,
|
||||
}
|
||||
|
||||
if (pos > end) {
|
||||
lyxerr << "dont like 2 please report" << endl;
|
||||
lyxerr << "dont like 2, pos: " << pos
|
||||
<< " size: " << para.size()
|
||||
<< " row.pos():" << row.pos()
|
||||
<< " par: " << par << endl;
|
||||
// This shouldn't happen.
|
||||
BOOST_ASSERT(false);
|
||||
}
|
||||
|
49
src/text3.C
49
src/text3.C
@ -90,9 +90,6 @@ namespace {
|
||||
void toggleAndShow(LCursor & cur, LyXText * text,
|
||||
LyXFont const & font, bool toggleall = true)
|
||||
{
|
||||
if (!cur.bv().available())
|
||||
return;
|
||||
|
||||
text->toggleFree(cur, font, toggleall);
|
||||
|
||||
if (font.language() != ignore_language ||
|
||||
@ -106,7 +103,6 @@ namespace {
|
||||
text->setCursor(cur, cur.par(), cur.pos(),
|
||||
false, !cur.boundary());
|
||||
}
|
||||
cur.update();
|
||||
}
|
||||
|
||||
|
||||
@ -120,17 +116,17 @@ namespace {
|
||||
}
|
||||
|
||||
|
||||
void finishChange(LCursor & cur, bool selecting = false)
|
||||
void finishChange(LCursor & cur, bool selecting)
|
||||
{
|
||||
finishUndo();
|
||||
moveCursor(cur, selecting);
|
||||
cur.bv().owner()->view_state_changed();
|
||||
}
|
||||
|
||||
|
||||
void mathDispatch(LCursor & cur, LyXText * text,
|
||||
FuncRequest const & cmd, bool display)
|
||||
{
|
||||
recordUndo(cur);
|
||||
string sel = cur.selectionAsString(false);
|
||||
lyxerr << "selection is: '" << sel << "'" << endl;
|
||||
|
||||
@ -341,6 +337,7 @@ void doInsertInset(LCursor & cur, LyXText * text,
|
||||
if (!inset)
|
||||
return;
|
||||
|
||||
recordUndo(cur);
|
||||
bool gotsel = false;
|
||||
if (cur.selection()) {
|
||||
cur.bv().owner()->dispatch(FuncRequest(LFUN_CUT));
|
||||
@ -410,19 +407,19 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
case LFUN_DELETE_WORD_FORWARD:
|
||||
cur.clearSelection();
|
||||
deleteWordForward(cur);
|
||||
finishChange(cur);
|
||||
finishChange(cur, false);
|
||||
break;
|
||||
|
||||
case LFUN_DELETE_WORD_BACKWARD:
|
||||
cur.clearSelection();
|
||||
deleteWordBackward(cur);
|
||||
finishChange(cur);
|
||||
finishChange(cur, false);
|
||||
break;
|
||||
|
||||
case LFUN_DELETE_LINE_FORWARD:
|
||||
cur.clearSelection();
|
||||
deleteLineForward(cur);
|
||||
finishChange(cur);
|
||||
finishChange(cur, false);
|
||||
break;
|
||||
|
||||
case LFUN_WORDRIGHT:
|
||||
@ -432,7 +429,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
cursorLeftOneWord(cur);
|
||||
else
|
||||
cursorRightOneWord(cur);
|
||||
finishChange(cur);
|
||||
finishChange(cur, false);
|
||||
break;
|
||||
|
||||
case LFUN_WORDLEFT:
|
||||
@ -442,21 +439,21 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
cursorRightOneWord(cur);
|
||||
else
|
||||
cursorLeftOneWord(cur);
|
||||
finishChange(cur);
|
||||
finishChange(cur, false);
|
||||
break;
|
||||
|
||||
case LFUN_BEGINNINGBUF:
|
||||
if (!cur.mark())
|
||||
cur.clearSelection();
|
||||
cursorTop(cur);
|
||||
finishChange(cur);
|
||||
finishChange(cur, false);
|
||||
break;
|
||||
|
||||
case LFUN_ENDBUF:
|
||||
if (!cur.mark())
|
||||
cur.clearSelection();
|
||||
cursorBottom(cur);
|
||||
finishChange(cur);
|
||||
finishChange(cur, false);
|
||||
break;
|
||||
|
||||
case LFUN_RIGHT:
|
||||
@ -569,7 +566,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
if (!cur.mark())
|
||||
cur.clearSelection();
|
||||
cursorUpParagraph(cur);
|
||||
finishChange(cur);
|
||||
finishChange(cur, false);
|
||||
break;
|
||||
|
||||
case LFUN_DOWN_PARAGRAPH:
|
||||
@ -634,7 +631,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
cutSelection(cur, true, false);
|
||||
}
|
||||
moveCursor(cur, false);
|
||||
bv->owner()->view_state_changed();
|
||||
break;
|
||||
|
||||
case LFUN_DELETE_SKIP:
|
||||
@ -664,7 +660,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
} else {
|
||||
cutSelection(cur, true, false);
|
||||
}
|
||||
bv->owner()->view_state_changed();
|
||||
bv->switchKeyMap();
|
||||
cur.update();
|
||||
break;
|
||||
@ -688,7 +683,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
cur.update();
|
||||
cur.resetAnchor();
|
||||
bv->switchKeyMap();
|
||||
bv->owner()->view_state_changed();
|
||||
break;
|
||||
|
||||
case LFUN_BREAKPARAGRAPHKEEPLAYOUT:
|
||||
@ -697,7 +691,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
cur.update();
|
||||
cur.resetAnchor();
|
||||
bv->switchKeyMap();
|
||||
bv->owner()->view_state_changed();
|
||||
break;
|
||||
|
||||
case LFUN_BREAKPARAGRAPH_SKIP: {
|
||||
@ -717,7 +710,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
cur.update();
|
||||
// anchor() = cur;
|
||||
bv->switchKeyMap();
|
||||
bv->owner()->view_state_changed();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -774,6 +766,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
}
|
||||
|
||||
case LFUN_INSET_INSERT: {
|
||||
recordUndo(cur);
|
||||
InsetBase * inset = createInset(bv, cmd);
|
||||
if (inset)
|
||||
insertInset(cur, inset);
|
||||
@ -1192,7 +1185,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
bv->haveSelection(cur.selection());
|
||||
|
||||
bv->switchKeyMap();
|
||||
bv->owner()->view_state_changed();
|
||||
bv->owner()->updateMenubar();
|
||||
bv->owner()->updateToolbar();
|
||||
break;
|
||||
@ -1229,7 +1221,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
// real_current_font.number can change so we need to
|
||||
// update the minibuffer
|
||||
if (old_font != real_current_font)
|
||||
bv->owner()->view_state_changed();
|
||||
bv->updateScrollbar();
|
||||
break;
|
||||
}
|
||||
@ -1341,7 +1332,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
LyXFont font(LyXFont::ALL_IGNORE);
|
||||
font.setEmph(LyXFont::TOGGLE);
|
||||
toggleAndShow(cur, this, font);
|
||||
bv->owner()->view_state_changed();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1349,7 +1339,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
LyXFont font(LyXFont::ALL_IGNORE);
|
||||
font.setSeries(LyXFont::BOLD_SERIES);
|
||||
toggleAndShow(cur, this, font);
|
||||
bv->owner()->view_state_changed();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1357,7 +1346,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
LyXFont font(LyXFont::ALL_IGNORE);
|
||||
font.setNoun(LyXFont::TOGGLE);
|
||||
toggleAndShow(cur, this, font);
|
||||
bv->owner()->view_state_changed();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1365,7 +1353,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
LyXFont font(LyXFont::ALL_IGNORE);
|
||||
font.setFamily(LyXFont::TYPEWRITER_FAMILY); // no good
|
||||
toggleAndShow(cur, this, font);
|
||||
bv->owner()->view_state_changed();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1373,7 +1360,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
LyXFont font(LyXFont::ALL_IGNORE);
|
||||
font.setFamily(LyXFont::SANS_FAMILY);
|
||||
toggleAndShow(cur, this, font);
|
||||
bv->owner()->view_state_changed();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1381,14 +1367,12 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
LyXFont font(LyXFont::ALL_IGNORE);
|
||||
font.setFamily(LyXFont::ROMAN_FAMILY);
|
||||
toggleAndShow(cur, this, font);
|
||||
bv->owner()->view_state_changed();
|
||||
break;
|
||||
}
|
||||
|
||||
case LFUN_DEFAULT: {
|
||||
LyXFont font(LyXFont::ALL_INHERIT, ignore_language);
|
||||
toggleAndShow(cur, this, font);
|
||||
bv->owner()->view_state_changed();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1396,7 +1380,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
LyXFont font(LyXFont::ALL_IGNORE);
|
||||
font.setUnderbar(LyXFont::TOGGLE);
|
||||
toggleAndShow(cur, this, font);
|
||||
bv->owner()->view_state_changed();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1404,7 +1387,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
LyXFont font(LyXFont::ALL_IGNORE);
|
||||
font.setLyXSize(cmd.argument);
|
||||
toggleAndShow(cur, this, font);
|
||||
bv->owner()->view_state_changed();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1416,13 +1398,11 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
font.setLanguage(lang);
|
||||
toggleAndShow(cur, this, font);
|
||||
bv->switchKeyMap();
|
||||
bv->owner()->view_state_changed();
|
||||
break;
|
||||
}
|
||||
|
||||
case LFUN_FREEFONT_APPLY:
|
||||
toggleAndShow(cur, this, freefont, toggleall);
|
||||
bv->owner()->view_state_changed();
|
||||
cur.message(_("Character set"));
|
||||
break;
|
||||
|
||||
@ -1435,7 +1415,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
freefont = font;
|
||||
toggleall = toggle;
|
||||
toggleAndShow(cur, this, freefont, toggleall);
|
||||
bv->owner()->view_state_changed();
|
||||
cur.message(_("Character set"));
|
||||
}
|
||||
break;
|
||||
@ -1519,7 +1498,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
if (tclass.floats().typeExist(cmd.argument)) {
|
||||
// not quite sure if we want this...
|
||||
recordUndo(cur);
|
||||
freezeUndo();
|
||||
cur.clearSelection();
|
||||
breakParagraph(cur);
|
||||
|
||||
@ -1530,8 +1508,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
|
||||
|
||||
setLayout(cur, tclass.defaultLayoutName());
|
||||
setParagraph(cur, Spacing(), LYX_ALIGN_LAYOUT, string(), 0);
|
||||
cur.insert(new InsetFloatList(cmd.argument));
|
||||
unFreezeUndo();
|
||||
insertInset(cur, new InsetFloatList(cmd.argument));
|
||||
} else {
|
||||
lyxerr << "Non-existent float type: "
|
||||
<< cmd.argument << endl;
|
||||
|
258
src/undo.C
258
src/undo.C
@ -20,10 +20,13 @@
|
||||
#include "cursor.h"
|
||||
#include "debug.h"
|
||||
#include "BufferView.h"
|
||||
#include "iterators.h"
|
||||
#include "lyxtext.h"
|
||||
#include "paragraph.h"
|
||||
|
||||
#include "mathed/math_support.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using lyx::paroffset_type;
|
||||
|
||||
|
||||
@ -38,46 +41,9 @@ bool undo_finished;
|
||||
|
||||
std::ostream & operator<<(std::ostream & os, Undo const & undo)
|
||||
{
|
||||
return os << " text: " << undo.text
|
||||
<< " index: " << undo.index
|
||||
<< " first: " << undo.first_par
|
||||
<< " from end: " << undo.end_par
|
||||
<< " cursor: " << undo.cursor_par
|
||||
<< "/" << undo.cursor_pos;
|
||||
}
|
||||
|
||||
|
||||
// translates LyXText pointer into offset count from document begin
|
||||
ParIterator text2pit(Buffer & buf, LyXText * text, int & tcount)
|
||||
{
|
||||
tcount = 0;
|
||||
ParIterator pit = buf.par_iterator_begin();
|
||||
ParIterator end = buf.par_iterator_end();
|
||||
|
||||
for ( ; pit != end; ++pit, ++tcount)
|
||||
if (pit.text(buf) == text)
|
||||
return pit;
|
||||
lyxerr << "undo: should not happen" << std::endl;
|
||||
return end;
|
||||
}
|
||||
|
||||
|
||||
// translates offset from buffer begin to ParIterator
|
||||
ParIterator num2pit(Buffer & buf, int num)
|
||||
{
|
||||
ParIterator pit = buf.par_iterator_begin();
|
||||
ParIterator end = buf.par_iterator_end();
|
||||
|
||||
for ( ; num && pit != end; ++pit, --num)
|
||||
;
|
||||
|
||||
if (pit != end)
|
||||
return pit;
|
||||
|
||||
// don't crash early...
|
||||
lyxerr << "undo: num2pit: num: " << num << std::endl;
|
||||
BOOST_ASSERT(false);
|
||||
return buf.par_iterator_begin();
|
||||
return os << " from: " << undo.from
|
||||
<< " end: " << undo.end
|
||||
<< " cursor:\n" << undo.cursor;
|
||||
}
|
||||
|
||||
|
||||
@ -85,126 +51,90 @@ void recordUndo(Undo::undo_kind kind,
|
||||
LCursor & cur, paroffset_type first_par, paroffset_type last_par,
|
||||
limited_stack<Undo> & stack)
|
||||
{
|
||||
#if 0
|
||||
DocumentIterator it = bufferBegin(cur.bv());
|
||||
DocumentIterator et = bufferEnd();
|
||||
size_t count = 0;
|
||||
for ( ; it != et; it.forwardPos(), ++count)
|
||||
if (it.top() == cur.top())
|
||||
lyxerr << "### found at " << count << std::endl;
|
||||
#endif
|
||||
BOOST_ASSERT(first_par <= cur.lastpar());
|
||||
BOOST_ASSERT(last_par <= cur.lastpar());
|
||||
|
||||
if (first_par > last_par) {
|
||||
paroffset_type t = first_par;
|
||||
first_par = last_par;
|
||||
last_par = t;
|
||||
}
|
||||
if (first_par > last_par)
|
||||
std::swap(first_par, last_par);
|
||||
|
||||
Buffer & buf = *cur.bv().buffer();
|
||||
int const end_par = cur.lastpar() + 1 - last_par;
|
||||
// create the position information of the Undo entry
|
||||
Undo undo;
|
||||
undo.kind = kind;
|
||||
undo.cursor = StableDocumentIterator(cur);
|
||||
undo.from = first_par;
|
||||
undo.end = cur.lastpar() - last_par;
|
||||
|
||||
// Undo::ATOMIC are always recorded (no overlapping there).
|
||||
// overlapping only with insert and delete inside one paragraph:
|
||||
// nobody wants all removed character appear one by one when undoing.
|
||||
if (!undo_finished && kind != Undo::ATOMIC) {
|
||||
// Check whether storing is needed.
|
||||
if (!buf.undostack().empty()
|
||||
&& buf.undostack().top().kind == kind
|
||||
&& buf.undostack().top().first_par == first_par
|
||||
&& buf.undostack().top().end_par == end_par) {
|
||||
// No additonal undo recording needed -
|
||||
// effectively, we combine undo recordings to one.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// push and fill the Undo entry
|
||||
if (cur.inTexted()) {
|
||||
stack.push(Undo());
|
||||
LyXText * text = cur.text();
|
||||
int textnum;
|
||||
ParIterator pit = text2pit(buf, text, textnum);
|
||||
Undo & undo = stack.top();
|
||||
undo.kind = kind;
|
||||
undo.text = textnum;
|
||||
undo.index = pit.index();
|
||||
undo.first_par = first_par;
|
||||
undo.end_par = end_par;
|
||||
undo.cursor_par = cur.par();
|
||||
undo.cursor_pos = cur.pos();
|
||||
undo.math = false;
|
||||
//lyxerr << "undo record: " << stack.top() << std::endl;
|
||||
// As nobody wants all removed character appear one by one when undoing,
|
||||
// we want combine 'similar' non-ATOMIC undo recordings to one.
|
||||
if (!undo_finished
|
||||
&& kind != Undo::ATOMIC
|
||||
&& !stack.empty()
|
||||
&& stack.top().cursor.size() == undo.cursor.size()
|
||||
&& stack.top().kind == undo.kind
|
||||
&& stack.top().from == undo.from
|
||||
&& stack.top().end == undo.end)
|
||||
return;
|
||||
|
||||
// fill in the real data to be saved
|
||||
if (cur.inMathed()) {
|
||||
// simply use the whole cell
|
||||
undo.array = asString(cur.cell());
|
||||
} else {
|
||||
// some more effort needed here as 'the whole cell' of the
|
||||
// main LyXText _is_ the whole document.
|
||||
// record the relevant paragraphs
|
||||
LyXText * text = cur.text();
|
||||
BOOST_ASSERT(text);
|
||||
ParagraphList & plist = text->paragraphs();
|
||||
ParagraphList::iterator first = plist.begin();
|
||||
advance(first, first_par);
|
||||
ParagraphList::iterator last = plist.begin();
|
||||
advance(last, last_par);
|
||||
|
||||
for (ParagraphList::iterator it = first; it != last; ++it)
|
||||
undo.pars.push_back(*it);
|
||||
undo.pars.push_back(*last);
|
||||
} else {
|
||||
BOOST_ASSERT(false); // not in mathed (yet)
|
||||
stack.push(Undo());
|
||||
Undo & undo = stack.top();
|
||||
undo.math = false;
|
||||
advance(last, last_par + 1);
|
||||
undo.pars = ParagraphList(first, last);
|
||||
}
|
||||
|
||||
// and make sure that next time, we should be combining if possible
|
||||
// push the undo entry to undo stack
|
||||
//lyxerr << "undo record: " << stack.top() << std::endl;
|
||||
stack.push(undo);
|
||||
|
||||
// next time we'll try again to combine entries if possible
|
||||
undo_finished = false;
|
||||
}
|
||||
|
||||
|
||||
// returns false if no undo possible
|
||||
bool performUndoOrRedo(BufferView & bv, Undo const & undo)
|
||||
void performUndoOrRedo(BufferView & bv, Undo const & undo)
|
||||
{
|
||||
Buffer & buf = *bv.buffer();
|
||||
LCursor & cur = bv.cursor();
|
||||
lyxerr << "undo, performing: " << undo << std::endl;
|
||||
ParIterator pit = num2pit(buf, undo.text);
|
||||
LyXText * text = pit.text(buf);
|
||||
ParagraphList & plist = text->paragraphs();
|
||||
cur.setCursor(undo.cursor.asDocumentIterator(bv), false);
|
||||
|
||||
// remove new stuff between first and last
|
||||
{
|
||||
ParagraphList::iterator first = plist.begin();
|
||||
advance(first, undo.first_par);
|
||||
ParagraphList::iterator last = plist.begin();
|
||||
advance(last, plist.size() - undo.end_par);
|
||||
plist.erase(first, ++last);
|
||||
}
|
||||
|
||||
// re-insert old stuff instead
|
||||
if (plist.empty()) {
|
||||
plist.assign(undo.pars.begin(), undo.pars.end());
|
||||
if (cur.inMathed()) {
|
||||
// We stored the full cell here as there is not much to be
|
||||
// gained by storing just 'a few' paragraphs (most if not
|
||||
// all math inset cells have just one paragraph!)
|
||||
asArray(undo.array, cur.cell());
|
||||
} else {
|
||||
// Some finer machinery is needed here.
|
||||
LyXText * text = cur.text();
|
||||
BOOST_ASSERT(text);
|
||||
ParagraphList & plist = text->paragraphs();
|
||||
|
||||
// remove new stuff between first and last
|
||||
ParagraphList::iterator first = plist.begin();
|
||||
advance(first, undo.first_par);
|
||||
advance(first, undo.from);
|
||||
ParagraphList::iterator last = plist.begin();
|
||||
advance(last, plist.size() - undo.end);
|
||||
plist.erase(first, last);
|
||||
|
||||
// re-insert old stuff instead
|
||||
first = plist.begin();
|
||||
advance(first, undo.from);
|
||||
plist.insert(first, undo.pars.begin(), undo.pars.end());
|
||||
}
|
||||
|
||||
// set cursor
|
||||
lyxerr << "undo, text: " << undo.text
|
||||
<< " inset: " << pit.inset()
|
||||
<< " index: " << undo.index
|
||||
<< " par: " << undo.cursor_par
|
||||
<< " pos: " << undo.cursor_pos
|
||||
<< std::endl;
|
||||
|
||||
text->updateCounters();
|
||||
|
||||
// rebreak the entire lyxtext
|
||||
#warning needed?
|
||||
text->redoParagraphs(buf.paragraphs().begin(), buf.paragraphs().end());
|
||||
bv.cursor().resetAnchor();
|
||||
|
||||
ParIterator pit2 = num2pit(buf, undo.text);
|
||||
advance(pit2, undo.cursor_par);
|
||||
bv.setCursor(pit2, undo.cursor_pos);
|
||||
|
||||
cur.resetAnchor();
|
||||
finishUndo();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -212,7 +142,6 @@ bool performUndoOrRedo(BufferView & bv, Undo const & undo)
|
||||
bool textUndoOrRedo(BufferView & bv,
|
||||
limited_stack<Undo> & stack, limited_stack<Undo> & otherstack)
|
||||
{
|
||||
Buffer & buf = *bv.buffer();
|
||||
if (stack.empty()) {
|
||||
// nothing to do
|
||||
finishUndo();
|
||||
@ -223,46 +152,38 @@ bool textUndoOrRedo(BufferView & bv,
|
||||
stack.pop();
|
||||
finishUndo();
|
||||
|
||||
// this implements redo
|
||||
if (!undo_frozen) {
|
||||
otherstack.push(undo);
|
||||
otherstack.top().pars.clear();
|
||||
ParIterator pit = num2pit(buf, undo.text);
|
||||
ParagraphList & plist = pit.plist();
|
||||
if (undo.first_par + undo.end_par <= int(plist.size())) {
|
||||
ParagraphList::iterator first = plist.begin();
|
||||
advance(first, undo.first_par);
|
||||
ParagraphList::iterator last = plist.begin();
|
||||
advance(last, plist.size() - undo.end_par + 1);
|
||||
otherstack.top().pars.insert(otherstack.top().pars.begin(), first, last);
|
||||
DocumentIterator dit = undo.cursor.asDocumentIterator(bv);
|
||||
if (dit.inMathed()) {
|
||||
// not much to be done
|
||||
} else {
|
||||
otherstack.top().pars.clear();
|
||||
LyXText * text = dit.text();
|
||||
BOOST_ASSERT(text);
|
||||
ParagraphList & plist = text->paragraphs();
|
||||
if (undo.from + undo.end <= int(plist.size())) {
|
||||
ParagraphList::iterator first = plist.begin();
|
||||
advance(first, undo.from);
|
||||
ParagraphList::iterator last = plist.begin();
|
||||
advance(last, plist.size() - undo.end);
|
||||
otherstack.top().pars.insert(otherstack.top().pars.begin(), first, last);
|
||||
}
|
||||
}
|
||||
otherstack.top().cursor_pos = bv.cursor().pos();
|
||||
otherstack.top().cursor_par = bv.cursor().par();
|
||||
lyxerr << " undo other: " << otherstack.top() << std::endl;
|
||||
otherstack.top().cursor = bv.cursor();
|
||||
//lyxerr << " undo other: " << otherstack.top() << std::endl;
|
||||
}
|
||||
|
||||
freezeUndo();
|
||||
bool const ret = performUndoOrRedo(bv, undo);
|
||||
unFreezeUndo();
|
||||
return ret;
|
||||
undo_frozen = true;
|
||||
performUndoOrRedo(bv, undo);
|
||||
undo_frozen = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace anon
|
||||
|
||||
|
||||
void freezeUndo()
|
||||
{
|
||||
// this is dangerous and for internal use only
|
||||
undo_frozen = true;
|
||||
}
|
||||
|
||||
|
||||
void unFreezeUndo()
|
||||
{
|
||||
// this is dangerous and for internal use only
|
||||
undo_frozen = false;
|
||||
}
|
||||
|
||||
|
||||
void finishUndo()
|
||||
{
|
||||
// makes sure the next operation will be stored
|
||||
@ -292,6 +213,9 @@ void recordUndo(Undo::undo_kind kind,
|
||||
Buffer * buf = cur.bv().buffer();
|
||||
recordUndo(kind, cur, first, last, buf->undostack());
|
||||
buf->redostack().clear();
|
||||
//lyxerr << "undostack:\n";
|
||||
//for (size_t i = 0, n = buf->undostack().size(); i != n && i < 6; ++i)
|
||||
// lyxerr << " " << i << ": " << buf->undostack()[i] << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
28
src/undo.h
28
src/undo.h
@ -16,7 +16,9 @@
|
||||
#ifndef UNDO_H
|
||||
#define UNDO_H
|
||||
|
||||
#include "dociterator.h"
|
||||
#include "ParagraphList_fwd.h"
|
||||
|
||||
#include "support/types.h"
|
||||
|
||||
#include <string>
|
||||
@ -49,24 +51,16 @@ struct Undo {
|
||||
|
||||
/// which kind of operation are we recording for?
|
||||
undo_kind kind;
|
||||
/// hosting LyXText counted from buffer begin
|
||||
int text;
|
||||
/// cell in a tabular or similar
|
||||
int index;
|
||||
/// offset to the first paragraph in the paragraph list
|
||||
int first_par;
|
||||
/// offset to the last paragraph from the end of paragraph list
|
||||
int end_par;
|
||||
/// offset to the first paragraph in the paragraph list
|
||||
int cursor_par;
|
||||
/// the position of the cursor in the hosting paragraph
|
||||
int cursor_pos;
|
||||
/// the position of the cursor
|
||||
StableDocumentIterator cursor;
|
||||
/// counted from begin of buffer
|
||||
lyx::paroffset_type from;
|
||||
/// complement to end of this cell
|
||||
lyx::paroffset_type end;
|
||||
/// the contents of the saved paragraphs (for texted)
|
||||
ParagraphList pars;
|
||||
/// the contents of the saved matharray (for mathed)
|
||||
std::string array;
|
||||
/// in mathed?
|
||||
bool math;
|
||||
};
|
||||
|
||||
|
||||
@ -79,12 +73,6 @@ bool textRedo(BufferView &);
|
||||
/// makes sure the next operation will be stored
|
||||
void finishUndo();
|
||||
|
||||
/// whilst undo is frozen, no actions gets added to the undo stack
|
||||
void freezeUndo();
|
||||
|
||||
/// track undos again
|
||||
void unFreezeUndo();
|
||||
|
||||
|
||||
/**
|
||||
* Record undo information - call with the current cursor and the 'other
|
||||
|
Loading…
x
Reference in New Issue
Block a user