mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-05 13:26:21 +00:00
In insets:
2003-10-14 Andr� P�nitz <poenitz@gmx.net> * insetcollapsable.[Ch]: * insettabular.[Ch]: * insettext.[Ch]: * inset.h: getText() as alternative to getParagraphs() In src: 2003-10-14 Andr� P�nitz <poenitz@gmx.net> * iterators.[Ch]: new direct access to innermost LyXText and Inset * undo.[Ch]: restoring part of 'undo in insets' * Makefile.am: * undo_funcs.[Ch]: merge with undo.[Ch] * tabular.C: small cleansing stuff git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@7919 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
5705714920
commit
5c2f0c5c46
@ -28,7 +28,7 @@
|
||||
#include "paragraph.h"
|
||||
#include "paragraph_funcs.h"
|
||||
#include "texrow.h"
|
||||
#include "undo_funcs.h"
|
||||
#include "undo.h"
|
||||
#include "WordLangTuple.h"
|
||||
|
||||
#include "frontends/Alert.h"
|
||||
|
@ -42,7 +42,7 @@
|
||||
#include "paragraph_funcs.h"
|
||||
#include "ParagraphParameters.h"
|
||||
#include "TextCache.h"
|
||||
#include "undo_funcs.h"
|
||||
#include "undo.h"
|
||||
#include "vspace.h"
|
||||
|
||||
#include "insets/insetfloatlist.h"
|
||||
|
@ -1,3 +1,16 @@
|
||||
|
||||
|
||||
2003-10-14 André Pönitz <poenitz@gmx.net>
|
||||
|
||||
* iterators.[Ch]: new direct access to innermost LyXText and Inset
|
||||
|
||||
* undo.[Ch]: restoring part of 'undo in insets'
|
||||
|
||||
* Makefile.am:
|
||||
* undo_funcs.[Ch]: merge with undo.[Ch]
|
||||
|
||||
* tabular.C: small cleansing stuff
|
||||
|
||||
2003-10-14 Alfredo Braunstein <abraunst@libero.it>
|
||||
|
||||
* paragraph_funcs.C (readParToken): report unknown insets as error
|
||||
|
@ -182,11 +182,9 @@ void InsetList::deleteInsetsLyXText(BufferView * bv)
|
||||
List::iterator it = list.begin();
|
||||
List::iterator end = list.end();
|
||||
for (; it != end; ++it) {
|
||||
if (it->inset) {
|
||||
if (it->inset->isTextInset()) {
|
||||
static_cast<UpdatableInset*>
|
||||
(it->inset)->deleteLyXText(bv, true);
|
||||
}
|
||||
if (it->inset && it->inset->isTextInset()) {
|
||||
static_cast<UpdatableInset*>
|
||||
(it->inset)->deleteLyXText(bv, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -260,8 +260,6 @@ lyx_SOURCES = \
|
||||
trans_mgr.h \
|
||||
undo.C \
|
||||
undo.h \
|
||||
undo_funcs.C \
|
||||
undo_funcs.h \
|
||||
vc-backend.C \
|
||||
vc-backend.h \
|
||||
version.C \
|
||||
|
@ -13,7 +13,6 @@
|
||||
#ifndef LYXDEBUG_H
|
||||
#define LYXDEBUG_H
|
||||
|
||||
|
||||
#include "support/debugstream.h"
|
||||
|
||||
/** Ideally this should have been a namespace, but since we try to be
|
||||
|
@ -1,3 +1,11 @@
|
||||
|
||||
2003-10-14 André Pönitz <poenitz@gmx.net>
|
||||
|
||||
* insetcollapsable.[Ch]:
|
||||
* insettabular.[Ch]:
|
||||
* insettext.[Ch]:
|
||||
* inset.h: getText() as alternative to getParagraphs()
|
||||
|
||||
2003-10-13 Angus Leeming <leeming@lyx.org>
|
||||
|
||||
* insetexternal.C:
|
||||
|
@ -233,6 +233,8 @@ public:
|
||||
/// should return it's very first one!
|
||||
virtual ParagraphList * getParagraphs(int /*num*/) const { return 0; }
|
||||
///
|
||||
virtual LyXText * getText(int /*num*/) const { return 0; }
|
||||
///
|
||||
virtual bool haveParagraphs() const {
|
||||
return false;
|
||||
}
|
||||
|
@ -456,6 +456,12 @@ ParagraphList * InsetCollapsable::getParagraphs(int i) const
|
||||
}
|
||||
|
||||
|
||||
LyXText * InsetCollapsable::getText(int i) const
|
||||
{
|
||||
return inset.getText(i);
|
||||
}
|
||||
|
||||
|
||||
LyXCursor const & InsetCollapsable::cursor(BufferView * bv) const
|
||||
{
|
||||
return inset.cursor(bv);
|
||||
|
@ -118,6 +118,8 @@ public:
|
||||
///
|
||||
ParagraphList * getParagraphs(int) const;
|
||||
///
|
||||
LyXText * getText(int) const;
|
||||
///
|
||||
LyXCursor const & cursor(BufferView *) const;
|
||||
///
|
||||
bool isOpen() const;
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "paragraph.h"
|
||||
#include "paragraph_funcs.h"
|
||||
#include "ParagraphParameters.h"
|
||||
#include "undo_funcs.h"
|
||||
#include "undo.h"
|
||||
#include "WordLangTuple.h"
|
||||
|
||||
#include "frontends/Alert.h"
|
||||
@ -427,13 +427,17 @@ bool InsetTabular::lockInsetInInset(BufferView * bv, UpdatableInset * inset)
|
||||
<< inset << "): ";
|
||||
if (!inset)
|
||||
return false;
|
||||
|
||||
oldcell = -1;
|
||||
|
||||
if (inset == &tabular.getCellInset(actcell)) {
|
||||
lyxerr[Debug::INSETTEXT] << "OK" << endl;
|
||||
the_locking_inset = &tabular.getCellInset(actcell);
|
||||
resetPos(bv);
|
||||
return true;
|
||||
} else if (!the_locking_inset) {
|
||||
}
|
||||
|
||||
if (!the_locking_inset) {
|
||||
int const n = tabular.getNumberOfCells();
|
||||
int const id = inset->id();
|
||||
for (int i = 0; i < n; ++i) {
|
||||
@ -451,13 +455,20 @@ bool InsetTabular::lockInsetInInset(BufferView * bv, UpdatableInset * inset)
|
||||
return the_locking_inset->lockInsetInInset(bv, inset);
|
||||
}
|
||||
}
|
||||
} else if (the_locking_inset && (the_locking_inset == inset)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (the_locking_inset && (the_locking_inset == inset)) {
|
||||
lyxerr[Debug::INSETTEXT] << "OK" << endl;
|
||||
resetPos(bv);
|
||||
} else if (the_locking_inset) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (the_locking_inset) {
|
||||
lyxerr[Debug::INSETTEXT] << "MAYBE" << endl;
|
||||
return the_locking_inset->lockInsetInInset(bv, inset);
|
||||
}
|
||||
|
||||
lyxerr[Debug::INSETTEXT] << "NOT OK" << endl;
|
||||
return false;
|
||||
}
|
||||
@ -551,7 +562,7 @@ void InsetTabular::lfunMousePress(FuncRequest const & cmd)
|
||||
|
||||
bool const inset_hit = insetHit(bv, cmd.x, cmd.y);
|
||||
|
||||
if ((ocell == actcell) && the_locking_inset && inset_hit) {
|
||||
if (ocell == actcell && the_locking_inset && inset_hit) {
|
||||
resetPos(bv);
|
||||
FuncRequest cmd1 = cmd;
|
||||
cmd1.x -= inset_x;
|
||||
@ -672,7 +683,9 @@ dispatch_result InsetTabular::localDispatch(FuncRequest const & cmd)
|
||||
clearSelection();
|
||||
finishUndo();
|
||||
if (insetHit(bv, cmd.x, cmd.y) && cmd.button() != mouse_button::button3) {
|
||||
activateCellInsetAbs(bv, cmd.x, cmd.y, cmd.button());
|
||||
inset_x = cursorx_ - top_x + tabular.getBeginningOfTextInCell(actcell);
|
||||
inset_y = cursory_;
|
||||
activateCellInset(bv, cmd.x - inset_x, cmd.y - inset_y, cmd.button());
|
||||
}
|
||||
}
|
||||
return DISPATCHED;
|
||||
@ -911,14 +924,12 @@ dispatch_result InsetTabular::localDispatch(FuncRequest const & cmd)
|
||||
case LFUN_ENDBUF:
|
||||
case LFUN_ENDBUFSEL:
|
||||
break;
|
||||
case LFUN_LAYOUT_TABULAR: {
|
||||
case LFUN_LAYOUT_TABULAR:
|
||||
InsetTabularMailer(*this).showDialog(bv);
|
||||
break;
|
||||
}
|
||||
case LFUN_INSET_DIALOG_UPDATE: {
|
||||
case LFUN_INSET_DIALOG_UPDATE:
|
||||
InsetTabularMailer(*this).updateDialog(bv);
|
||||
break;
|
||||
}
|
||||
case LFUN_TABULAR_FEATURE:
|
||||
if (!tabularFeatures(bv, arg))
|
||||
result = UNDISPATCHED;
|
||||
@ -954,8 +965,8 @@ dispatch_result InsetTabular::localDispatch(FuncRequest const & cmd)
|
||||
break;
|
||||
case LFUN_PASTESELECTION:
|
||||
{
|
||||
string const clip(bv->getClipboard());
|
||||
if (clip.empty())
|
||||
string const clip = bv->getClipboard();
|
||||
if (clip.empty())
|
||||
break;
|
||||
#if 0
|
||||
if (clip.find('\t') != string::npos) {
|
||||
@ -1380,10 +1391,9 @@ dispatch_result InsetTabular::moveLeft(BufferView * bv, bool lock)
|
||||
bool moved = isRightToLeft(bv) ? moveNextCell(bv) : movePrevCell(bv);
|
||||
if (!moved)
|
||||
return FINISHED;
|
||||
if (lock) { // behind the inset
|
||||
if (activateCellInset(bv, 0, 0, mouse_button::none, true))
|
||||
return DISPATCHED;
|
||||
}
|
||||
// behind the inset
|
||||
if (lock && activateCellInset(bv, 0, 0, mouse_button::none, true))
|
||||
return DISPATCHED;
|
||||
resetPos(bv);
|
||||
return DISPATCHED_NOUPDATE;
|
||||
}
|
||||
@ -1506,8 +1516,8 @@ void InsetTabular::setFont(BufferView * bv, LyXFont const & font, bool tall,
|
||||
int sel_col_start;
|
||||
int sel_col_end;
|
||||
getSelection(sel_row_start, sel_row_end, sel_col_start, sel_col_end);
|
||||
for(int i = sel_row_start; i <= sel_row_end; ++i)
|
||||
for(int j = sel_col_start; j <= sel_col_end; ++j)
|
||||
for (int i = sel_row_start; i <= sel_row_end; ++i)
|
||||
for (int j = sel_col_start; j <= sel_col_end; ++j)
|
||||
tabular.getCellInset(i, j).setFont(bv, font, tall, true);
|
||||
|
||||
if (!frozen)
|
||||
@ -1569,8 +1579,7 @@ void checkLongtableSpecial(LyXTabular::ltType & ltt,
|
||||
|
||||
|
||||
void InsetTabular::tabularFeatures(BufferView * bv,
|
||||
LyXTabular::Feature feature,
|
||||
string const & value)
|
||||
LyXTabular::Feature feature, string const & value)
|
||||
{
|
||||
int sel_col_start;
|
||||
int sel_col_end;
|
||||
@ -1635,8 +1644,7 @@ void InsetTabular::tabularFeatures(BufferView * bv,
|
||||
|
||||
switch (feature) {
|
||||
|
||||
case LyXTabular::SET_PWIDTH:
|
||||
{
|
||||
case LyXTabular::SET_PWIDTH: {
|
||||
LyXLength const len(value);
|
||||
LyXLength const & oldlen = tabular.getColumnPWidth(actcell);
|
||||
|
||||
@ -1672,11 +1680,13 @@ void InsetTabular::tabularFeatures(BufferView * bv,
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LyXTabular::SET_SPECIAL_COLUMN:
|
||||
case LyXTabular::SET_SPECIAL_MULTI:
|
||||
tabular.setAlignSpecial(actcell,value,feature);
|
||||
updateLocal(bv);
|
||||
break;
|
||||
|
||||
case LyXTabular::APPEND_ROW:
|
||||
// append the row into the tabular
|
||||
unlockInsetInInset(bv, the_locking_inset);
|
||||
@ -1684,6 +1694,7 @@ void InsetTabular::tabularFeatures(BufferView * bv,
|
||||
tabular.setOwner(this);
|
||||
updateLocal(bv);
|
||||
break;
|
||||
|
||||
case LyXTabular::APPEND_COLUMN:
|
||||
// append the column into the tabular
|
||||
unlockInsetInInset(bv, the_locking_inset);
|
||||
@ -1692,32 +1703,32 @@ void InsetTabular::tabularFeatures(BufferView * bv,
|
||||
actcell = tabular.getCellNumber(row, column);
|
||||
updateLocal(bv);
|
||||
break;
|
||||
|
||||
case LyXTabular::DELETE_ROW:
|
||||
unlockInsetInInset(bv, the_locking_inset);
|
||||
for(int i = sel_row_start; i <= sel_row_end; ++i) {
|
||||
for (int i = sel_row_start; i <= sel_row_end; ++i)
|
||||
tabular.deleteRow(sel_row_start);
|
||||
}
|
||||
if (sel_row_start >= tabular.rows())
|
||||
--sel_row_start;
|
||||
actcell = tabular.getCellNumber(sel_row_start, column);
|
||||
clearSelection();
|
||||
updateLocal(bv);
|
||||
break;
|
||||
|
||||
case LyXTabular::DELETE_COLUMN:
|
||||
unlockInsetInInset(bv, the_locking_inset);
|
||||
for(int i = sel_col_start; i <= sel_col_end; ++i) {
|
||||
for (int i = sel_col_start; i <= sel_col_end; ++i)
|
||||
tabular.deleteColumn(sel_col_start);
|
||||
}
|
||||
if (sel_col_start >= tabular.columns())
|
||||
--sel_col_start;
|
||||
actcell = tabular.getCellNumber(row, sel_col_start);
|
||||
clearSelection();
|
||||
updateLocal(bv);
|
||||
break;
|
||||
|
||||
case LyXTabular::M_TOGGLE_LINE_TOP:
|
||||
flag = false;
|
||||
case LyXTabular::TOGGLE_LINE_TOP:
|
||||
{
|
||||
case LyXTabular::TOGGLE_LINE_TOP: {
|
||||
bool lineSet = !tabular.topLine(actcell, flag);
|
||||
for (int i = sel_row_start; i <= sel_row_end; ++i)
|
||||
for (int j = sel_col_start; j <= sel_col_end; ++j)
|
||||
@ -1730,8 +1741,7 @@ void InsetTabular::tabularFeatures(BufferView * bv,
|
||||
|
||||
case LyXTabular::M_TOGGLE_LINE_BOTTOM:
|
||||
flag = false;
|
||||
case LyXTabular::TOGGLE_LINE_BOTTOM:
|
||||
{
|
||||
case LyXTabular::TOGGLE_LINE_BOTTOM: {
|
||||
bool lineSet = !tabular.bottomLine(actcell, flag);
|
||||
for (int i = sel_row_start; i <= sel_row_end; ++i)
|
||||
for (int j = sel_col_start; j <= sel_col_end; ++j)
|
||||
@ -1745,8 +1755,7 @@ void InsetTabular::tabularFeatures(BufferView * bv,
|
||||
|
||||
case LyXTabular::M_TOGGLE_LINE_LEFT:
|
||||
flag = false;
|
||||
case LyXTabular::TOGGLE_LINE_LEFT:
|
||||
{
|
||||
case LyXTabular::TOGGLE_LINE_LEFT: {
|
||||
bool lineSet = !tabular.leftLine(actcell, flag);
|
||||
for (int i = sel_row_start; i <= sel_row_end; ++i)
|
||||
for (int j = sel_col_start; j <= sel_col_end; ++j)
|
||||
@ -1760,8 +1769,7 @@ void InsetTabular::tabularFeatures(BufferView * bv,
|
||||
|
||||
case LyXTabular::M_TOGGLE_LINE_RIGHT:
|
||||
flag = false;
|
||||
case LyXTabular::TOGGLE_LINE_RIGHT:
|
||||
{
|
||||
case LyXTabular::TOGGLE_LINE_RIGHT: {
|
||||
bool lineSet = !tabular.rightLine(actcell, flag);
|
||||
for (int i = sel_row_start; i <= sel_row_end; ++i)
|
||||
for (int j = sel_col_start; j <= sel_col_end; ++j)
|
||||
@ -1873,7 +1881,7 @@ void InsetTabular::tabularFeatures(BufferView * bv,
|
||||
|
||||
case LyXTabular::SET_ROTATE_CELL:
|
||||
for (int i = sel_row_start; i <= sel_row_end; ++i)
|
||||
for (int j = sel_col_start; j<=sel_col_end; ++j)
|
||||
for (int j = sel_col_start; j <= sel_col_end; ++j)
|
||||
tabular.setRotateCell(
|
||||
tabular.getCellNumber(i, j), true);
|
||||
break;
|
||||
@ -1927,11 +1935,9 @@ void InsetTabular::tabularFeatures(BufferView * bv,
|
||||
tabular.setLTFoot(row, flag, ltt, true);
|
||||
break;
|
||||
|
||||
case LyXTabular::SET_LTNEWPAGE: {
|
||||
bool what = !tabular.getLTNewPage(row);
|
||||
tabular.setLTNewPage(row, what);
|
||||
case LyXTabular::SET_LTNEWPAGE:
|
||||
tabular.setLTNewPage(row, !tabular.getLTNewPage(row));
|
||||
break;
|
||||
}
|
||||
|
||||
// dummy stuff just to avoid warnings
|
||||
case LyXTabular::LAST_ACTION:
|
||||
@ -1961,15 +1967,6 @@ bool InsetTabular::activateCellInset(BufferView * bv, int x, int y,
|
||||
}
|
||||
|
||||
|
||||
bool InsetTabular::activateCellInsetAbs(BufferView * bv, int x, int y,
|
||||
mouse_button::state button)
|
||||
{
|
||||
inset_x = cursorx_ - top_x + tabular.getBeginningOfTextInCell(actcell);
|
||||
inset_y = cursory_;
|
||||
return activateCellInset(bv, x - inset_x, y - inset_y, button);
|
||||
}
|
||||
|
||||
|
||||
bool InsetTabular::insetHit(BufferView *, int x, int) const
|
||||
{
|
||||
return x + top_x > cursorx_ + tabular.getBeginningOfTextInCell(actcell);
|
||||
@ -2353,12 +2350,20 @@ void InsetTabular::getSelection(int & srow, int & erow,
|
||||
|
||||
ParagraphList * InsetTabular::getParagraphs(int i) const
|
||||
{
|
||||
return (i < tabular.getNumberOfCells())
|
||||
return i < tabular.getNumberOfCells()
|
||||
? tabular.getCellInset(i).getParagraphs(0)
|
||||
: 0;
|
||||
}
|
||||
|
||||
|
||||
LyXText * InsetTabular::getText(int i) const
|
||||
{
|
||||
return i < tabular.getNumberOfCells()
|
||||
? tabular.getCellInset(i).getText(0)
|
||||
: 0;
|
||||
}
|
||||
|
||||
|
||||
LyXCursor const & InsetTabular::cursor(BufferView * bv) const
|
||||
{
|
||||
if (the_locking_inset)
|
||||
@ -2387,7 +2392,8 @@ WordLangTuple const
|
||||
InsetTabular::selectNextWordToSpellcheck(BufferView * bv, float & value) const
|
||||
{
|
||||
if (the_locking_inset) {
|
||||
WordLangTuple word(the_locking_inset->selectNextWordToSpellcheck(bv, value));
|
||||
WordLangTuple word =
|
||||
the_locking_inset->selectNextWordToSpellcheck(bv, value);
|
||||
if (!word.word().empty())
|
||||
return word;
|
||||
if (tabular.isLastCell(actcell)) {
|
||||
@ -2399,7 +2405,7 @@ InsetTabular::selectNextWordToSpellcheck(BufferView * bv, float & value) const
|
||||
// otherwise we have to lock the next inset and ask for it's selecttion
|
||||
tabular.getCellInset(actcell)
|
||||
.localDispatch(FuncRequest(bv, LFUN_INSET_EDIT));
|
||||
WordLangTuple word(selectNextWordInt(bv, value));
|
||||
WordLangTuple word = selectNextWordInt(bv, value);
|
||||
if (!word.word().empty())
|
||||
resetPos(bv);
|
||||
return word;
|
||||
@ -2411,7 +2417,8 @@ WordLangTuple InsetTabular::selectNextWordInt(BufferView * bv, float & value) co
|
||||
// when entering this function the inset should be ALWAYS locked!
|
||||
BOOST_ASSERT(the_locking_inset);
|
||||
|
||||
WordLangTuple word(the_locking_inset->selectNextWordToSpellcheck(bv, value));
|
||||
WordLangTuple word =
|
||||
the_locking_inset->selectNextWordToSpellcheck(bv, value);
|
||||
if (!word.word().empty())
|
||||
return word;
|
||||
|
||||
@ -2571,7 +2578,7 @@ bool InsetTabular::insertAsciiString(BufferView * bv, string const & buf,
|
||||
++cols;
|
||||
break;
|
||||
case '\n':
|
||||
if ((p+1) < len)
|
||||
if (p + 1 < len)
|
||||
++rows;
|
||||
maxCols = max(cols, maxCols);
|
||||
cols = 1;
|
||||
|
@ -161,6 +161,8 @@ public:
|
||||
///
|
||||
ParagraphList * getParagraphs(int) const;
|
||||
///
|
||||
LyXText * getText(int) const;
|
||||
///
|
||||
LyXCursor const & cursor(BufferView *) const;
|
||||
///
|
||||
bool allowSpellcheck() const { return true; }
|
||||
@ -261,9 +263,6 @@ private:
|
||||
mouse_button::state button = mouse_button::none,
|
||||
bool behind = false);
|
||||
///
|
||||
bool activateCellInsetAbs(BufferView *, int x = 0, int y = 0,
|
||||
mouse_button::state button = mouse_button::none);
|
||||
///
|
||||
bool insetHit(BufferView * bv, int x, int y) const;
|
||||
///
|
||||
bool hasPasteBuffer() const;
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include "rowpainter.h"
|
||||
#include "sgml.h"
|
||||
#include "texrow.h"
|
||||
#include "undo_funcs.h"
|
||||
#include "undo.h"
|
||||
#include "WordLangTuple.h"
|
||||
|
||||
#include "frontends/Alert.h"
|
||||
@ -1582,6 +1582,12 @@ ParagraphList * InsetText::getParagraphs(int i) const
|
||||
}
|
||||
|
||||
|
||||
LyXText * InsetText::getText(int i) const
|
||||
{
|
||||
return (i == 0) ? const_cast<LyXText*>(&text_) : 0;
|
||||
}
|
||||
|
||||
|
||||
LyXCursor const & InsetText::cursor(BufferView * bv) const
|
||||
{
|
||||
if (the_locking_inset)
|
||||
|
@ -155,6 +155,8 @@ public:
|
||||
///
|
||||
ParagraphList * getParagraphs(int) const;
|
||||
///
|
||||
LyXText * getText(int) const;
|
||||
///
|
||||
LyXCursor const & cursor(BufferView *) const;
|
||||
///
|
||||
bool allowSpellcheck() const { return true; }
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "iterators.h"
|
||||
#include "paragraph.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include "insets/inset.h"
|
||||
|
||||
@ -146,6 +147,28 @@ ParIterator & ParIterator::operator++()
|
||||
}
|
||||
|
||||
|
||||
LyXText * ParIterator::text() const
|
||||
{
|
||||
//lyxerr << "positions.size: " << pimpl_->positions.size() << std::endl;
|
||||
if (pimpl_->positions.size() <= 1)
|
||||
return 0;
|
||||
|
||||
ParPosition const & pos = pimpl_->positions[pimpl_->positions.size() - 2];
|
||||
return (*pos.it)->inset->getText(*pos.index);
|
||||
}
|
||||
|
||||
|
||||
InsetOld * ParIterator::inset() const
|
||||
{
|
||||
//lyxerr << "positions.size: " << pimpl_->positions.size() << std::endl;
|
||||
if (pimpl_->positions.size() <= 1)
|
||||
return 0;
|
||||
|
||||
ParPosition const & pos = pimpl_->positions[pimpl_->positions.size() - 2];
|
||||
return (*pos.it)->inset;
|
||||
}
|
||||
|
||||
|
||||
Paragraph & ParIterator::operator*() const
|
||||
{
|
||||
return *pimpl_->positions.back().pit;
|
||||
|
@ -16,6 +16,9 @@
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
class LyXText;
|
||||
class InsetOld;
|
||||
|
||||
class ParIterator {
|
||||
public:
|
||||
///
|
||||
@ -38,6 +41,11 @@ public:
|
||||
ParagraphList::iterator pit() const;
|
||||
///
|
||||
ParagraphList & plist() const;
|
||||
/// returns 'innermost' LyXText if in an inset or '0' instead of
|
||||
//bv->text
|
||||
LyXText * text() const;
|
||||
///
|
||||
InsetOld * inset() const;
|
||||
///
|
||||
size_t size() const;
|
||||
///
|
||||
|
@ -49,7 +49,7 @@
|
||||
#include "paragraph.h"
|
||||
#include "ParagraphParameters.h"
|
||||
#include "TextCache.h"
|
||||
#include "undo_funcs.h"
|
||||
#include "undo.h"
|
||||
|
||||
#include "insets/insetcommand.h"
|
||||
#include "insets/insetexternal.h"
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include "math_hullinset.h"
|
||||
#include "math_parser.h"
|
||||
#include "math_spaceinset.h"
|
||||
#include "undo_funcs.h"
|
||||
#include "undo.h"
|
||||
#include "ref_inset.h"
|
||||
#include "LColor.h"
|
||||
|
||||
|
@ -487,7 +487,7 @@ void Paragraph::setFont(pos_type pos, LyXFont const & font)
|
||||
BOOST_ASSERT(pos <= size());
|
||||
|
||||
// First, reduce font against layout/label font
|
||||
// Update: The SetCharFont() routine in text2.C already
|
||||
// Update: The setCharFont() routine in text2.C already
|
||||
// reduces font, so we don't need to do that here. (Asger)
|
||||
// No need to simplify this because it will disappear
|
||||
// in a new kernel. (Asger)
|
||||
|
@ -69,6 +69,11 @@ public:
|
||||
/// the destructor removes the new paragraph from the list
|
||||
~Paragraph();
|
||||
|
||||
///
|
||||
int id() const;
|
||||
///
|
||||
void id(int i);
|
||||
|
||||
///
|
||||
Language const * getParLanguage(BufferParams const &) const;
|
||||
///
|
||||
@ -91,11 +96,6 @@ public:
|
||||
///
|
||||
void validate(LaTeXFeatures &) const;
|
||||
|
||||
/// return the unique ID of this paragraph
|
||||
int id() const;
|
||||
/// Set the Id of this paragraph.
|
||||
void id(int);
|
||||
|
||||
///
|
||||
int startTeXParParams(BufferParams const &, std::ostream &, bool) const;
|
||||
|
||||
|
@ -12,8 +12,9 @@
|
||||
#ifndef DEBUG_STREAM_HPP
|
||||
#define DEBUG_STREAM_HPP
|
||||
|
||||
#include <boost/test/detail/nullstream.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/test/detail/nullstream.hpp>
|
||||
|
||||
struct debug_trait {
|
||||
enum type {
|
||||
|
17
src/text.C
17
src/text.C
@ -36,7 +36,7 @@
|
||||
#include "ParagraphParameters.h"
|
||||
#include "rowpainter.h"
|
||||
#include "text_funcs.h"
|
||||
#include "undo_funcs.h"
|
||||
#include "undo.h"
|
||||
#include "vspace.h"
|
||||
#include "WordLangTuple.h"
|
||||
|
||||
@ -1284,7 +1284,7 @@ void LyXText::redoParagraph()
|
||||
// same Paragraph one to the right and make a rebreak
|
||||
void LyXText::insertChar(char c)
|
||||
{
|
||||
recordUndo(bv(), Undo::INSERT, ownerParagraphs(), cursor.par(), cursor.par());
|
||||
recordUndo(Undo::INSERT, this, cursor.par(), cursor.par());
|
||||
|
||||
// When the free-spacing option is set for the current layout,
|
||||
// disable the double-space checking
|
||||
@ -1568,7 +1568,7 @@ void LyXText::acceptChange()
|
||||
if (selection.start.par() == selection.end.par()) {
|
||||
LyXCursor & startc = selection.start;
|
||||
LyXCursor & endc = selection.end;
|
||||
recordUndo(bv(), Undo::INSERT, ownerParagraphs(), startc.par());
|
||||
recordUndo(Undo::INSERT, this, startc.par());
|
||||
getPar(startc)->acceptChange(startc.pos(), endc.pos());
|
||||
finishUndo();
|
||||
clearSelection();
|
||||
@ -1587,7 +1587,7 @@ void LyXText::rejectChange()
|
||||
if (selection.start.par() == selection.end.par()) {
|
||||
LyXCursor & startc = selection.start;
|
||||
LyXCursor & endc = selection.end;
|
||||
recordUndo(bv(), Undo::INSERT, ownerParagraphs(), startc.par());
|
||||
recordUndo(Undo::INSERT, this, startc.par());
|
||||
getPar(startc)->rejectChange(startc.pos(), endc.pos());
|
||||
finishUndo();
|
||||
clearSelection();
|
||||
@ -1797,7 +1797,7 @@ void LyXText::changeCase(LyXText::TextCase action)
|
||||
setCursor(to.par(), to.pos() + 1);
|
||||
}
|
||||
|
||||
recordUndo(bv(), Undo::ATOMIC, ownerParagraphs(), from.par(), to.par());
|
||||
recordUndo(Undo::ATOMIC, this, from.par(), to.par());
|
||||
|
||||
pos_type pos = from.pos();
|
||||
int par = from.par();
|
||||
@ -1858,7 +1858,7 @@ void LyXText::Delete()
|
||||
|
||||
// if you had success make a backspace
|
||||
if (old_cursor.par() != cursor.par() || old_cursor.pos() != cursor.pos()) {
|
||||
recordUndo(bv(), Undo::DELETE, ownerParagraphs(), old_cursor.par());
|
||||
recordUndo(Undo::DELETE, this, old_cursor.par());
|
||||
backspace();
|
||||
}
|
||||
}
|
||||
@ -1908,8 +1908,7 @@ void LyXText::backspace()
|
||||
}
|
||||
|
||||
if (cursor.par() != 0)
|
||||
recordUndo(bv(), Undo::DELETE, ownerParagraphs(),
|
||||
cursor.par() - 1, cursor.par());
|
||||
recordUndo(Undo::DELETE, this, cursor.par() - 1, cursor.par());
|
||||
|
||||
ParagraphList::iterator tmppit = cursorPar();
|
||||
// We used to do cursorLeftIntern() here, but it is
|
||||
@ -1948,7 +1947,7 @@ void LyXText::backspace()
|
||||
} else {
|
||||
// this is the code for a normal backspace, not pasting
|
||||
// any paragraphs
|
||||
recordUndo(bv(), Undo::DELETE, ownerParagraphs(), cursor.par());
|
||||
recordUndo(Undo::DELETE, this, cursor.par());
|
||||
// We used to do cursorLeftIntern() here, but it is
|
||||
// not a good idea since it triggers the auto-delete
|
||||
// mechanism. So we do a cursorLeftIntern()-lite,
|
||||
|
@ -42,7 +42,7 @@
|
||||
#include "paragraph.h"
|
||||
#include "paragraph_funcs.h"
|
||||
#include "ParagraphParameters.h"
|
||||
#include "undo_funcs.h"
|
||||
#include "undo.h"
|
||||
#include "vspace.h"
|
||||
|
||||
#include "frontends/font_metrics.h"
|
||||
@ -1938,13 +1938,13 @@ ParagraphList & LyXText::ownerParagraphs() const
|
||||
|
||||
void LyXText::recUndo(paroffset_type first, paroffset_type last) const
|
||||
{
|
||||
recordUndo(bv(), Undo::ATOMIC, ownerParagraphs(), first, last);
|
||||
recordUndo(Undo::ATOMIC, this, first, last);
|
||||
}
|
||||
|
||||
|
||||
void LyXText::recUndo(lyx::paroffset_type par) const
|
||||
{
|
||||
recordUndo(bv(), Undo::ATOMIC, ownerParagraphs(), par, par);
|
||||
recordUndo(Undo::ATOMIC, this, par, par);
|
||||
}
|
||||
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include "paragraph.h"
|
||||
#include "ParagraphParameters.h"
|
||||
#include "text_funcs.h"
|
||||
#include "undo_funcs.h"
|
||||
#include "undo.h"
|
||||
#include "vspace.h"
|
||||
|
||||
#include "frontends/Dialogs.h"
|
||||
|
278
src/undo.C
278
src/undo.C
@ -3,8 +3,11 @@
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Asger Alstrup
|
||||
* \author Lars Gullik Bjønnes
|
||||
* \author John Levon
|
||||
* \author André Pönitz
|
||||
* \author Jürgen Vigna
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
@ -12,17 +15,37 @@
|
||||
#include <config.h>
|
||||
|
||||
#include "undo.h"
|
||||
|
||||
#include "buffer.h"
|
||||
#include "debug.h"
|
||||
#include "BufferView.h"
|
||||
#include "funcrequest.h"
|
||||
#include "iterators.h"
|
||||
#include "lyxtext.h"
|
||||
#include "paragraph.h"
|
||||
|
||||
Undo::Undo(undo_kind kind_arg, int inset,
|
||||
int plist_arg,
|
||||
#include "insets/updatableinset.h"
|
||||
#include "insets/insettext.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using std::endl;
|
||||
using lyx::paroffset_type;
|
||||
|
||||
|
||||
/// The flag used by finishUndo().
|
||||
bool undo_finished;
|
||||
|
||||
/// Whether actions are not added to the undo stacks.
|
||||
bool undo_frozen;
|
||||
|
||||
Undo::Undo(undo_kind kind_arg, int text_arg,
|
||||
int first, int last,
|
||||
int cursor, int cursor_pos_arg,
|
||||
ParagraphList const & par)
|
||||
:
|
||||
kind(kind_arg),
|
||||
inset_id(inset),
|
||||
plist(plist_arg),
|
||||
text(text_arg),
|
||||
first_par_offset(first),
|
||||
last_par_offset(last),
|
||||
cursor_par_offset(cursor),
|
||||
@ -30,3 +53,250 @@ Undo::Undo(undo_kind kind_arg, int inset,
|
||||
pars(par)
|
||||
{}
|
||||
|
||||
|
||||
std::ostream & operator<<(std::ostream & os, Undo const & undo)
|
||||
{
|
||||
return os << " text: " << undo.text
|
||||
<< " first: " << undo.first_par_offset
|
||||
<< " last: " << undo.last_par_offset
|
||||
<< " cursor: " << undo.cursor_par_offset
|
||||
<< "/" << undo.cursor_pos;
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
void recordUndo(Undo::undo_kind kind,
|
||||
LyXText * text, paroffset_type firstpar, paroffset_type lastpar,
|
||||
limited_stack<Undo> & stack)
|
||||
{
|
||||
Buffer * buf = text->bv()->buffer();
|
||||
|
||||
ParagraphList & plist = text->ownerParagraphs();
|
||||
ParagraphList::iterator first = plist.begin();
|
||||
advance(first, firstpar);
|
||||
ParagraphList::iterator last = plist.begin();
|
||||
advance(last, lastpar);
|
||||
|
||||
// try to find the appropriate list by counting the
|
||||
// texts from buffer begin
|
||||
ParIterator null = buf->par_iterator_end();
|
||||
|
||||
int tcount = 0;
|
||||
// it.text() returns 0 for outermost text.
|
||||
if (text != text->bv()->text)
|
||||
for (ParIterator it = buf->par_iterator_begin(); it != null; ++it, ++tcount)
|
||||
if (it.text() == text)
|
||||
break;
|
||||
|
||||
// and calculate a stable reference to them
|
||||
int const first_offset = firstpar;
|
||||
int const last_offset = plist.size() - lastpar;
|
||||
|
||||
// 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_offset == first_offset
|
||||
&& buf->undostack().top().last_par_offset == last_offset) {
|
||||
// No additonal undo recording needed -
|
||||
// effectively, we combine undo recordings to one.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Record the cursor position in a stable way.
|
||||
int const cursor_offset = text->cursor.par();
|
||||
|
||||
// make and push the Undo entry
|
||||
stack.push(Undo(kind, tcount,
|
||||
first_offset, last_offset,
|
||||
cursor_offset, text->cursor.pos(),
|
||||
ParagraphList()));
|
||||
lyxerr << "undo record: " << stack.top() << endl;
|
||||
|
||||
// record the relevant paragraphs
|
||||
ParagraphList & undo_pars = stack.top().pars;
|
||||
|
||||
for (ParagraphList::iterator it = first; it != last; ++it) {
|
||||
undo_pars.push_back(*it);
|
||||
undo_pars.back().id(it->id());
|
||||
}
|
||||
undo_pars.push_back(*last);
|
||||
undo_pars.back().id(last->id());
|
||||
|
||||
// and make sure that next time, we should be combining if possible
|
||||
undo_finished = false;
|
||||
}
|
||||
|
||||
|
||||
// Returns false if no undo possible.
|
||||
bool performUndoOrRedo(BufferView * bv, Undo const & undo)
|
||||
{
|
||||
lyxerr << "undo, performing: " << undo << endl;
|
||||
Buffer * buf = bv->buffer();
|
||||
ParIterator plit = buf->par_iterator_begin();
|
||||
ParIterator null = buf->par_iterator_end();
|
||||
|
||||
int tcount = undo.text;
|
||||
for ( ; tcount && plit != null; ++plit, --tcount)
|
||||
;
|
||||
|
||||
LyXText * text = plit.text();
|
||||
if (!text)
|
||||
text = bv->text;
|
||||
ParagraphList & plist = text->ownerParagraphs();
|
||||
|
||||
// remove new stuff between first and last
|
||||
{
|
||||
ParagraphList::iterator first = plist.begin();
|
||||
advance(first, undo.first_par_offset);
|
||||
ParagraphList::iterator last = plist.begin();
|
||||
advance(last, plist.size() - undo.last_par_offset);
|
||||
plist.erase(first, ++last);
|
||||
}
|
||||
|
||||
// re-insert old stuff instead
|
||||
if (plist.empty()) {
|
||||
plist.assign(undo.pars.begin(), undo.pars.end());
|
||||
} else {
|
||||
ParagraphList::iterator first = plist.begin();
|
||||
advance(first, undo.first_par_offset);
|
||||
plist.insert(first, undo.pars.begin(), undo.pars.end());
|
||||
}
|
||||
|
||||
// set cursor
|
||||
lyxerr << "undo, text: " << text << " inset: " << plit.inset() << endl;
|
||||
InsetOld * inset = plit.inset();
|
||||
if (inset) {
|
||||
// Magic needed to cope with inset locking
|
||||
FuncRequest cmd(bv, LFUN_INSET_EDIT, "left");
|
||||
inset->localDispatch(cmd);
|
||||
}
|
||||
|
||||
// set cursor again to force the position to be the right one
|
||||
text->setCursorIntern(undo.cursor_par_offset, undo.cursor_pos);
|
||||
|
||||
// clear any selection
|
||||
text->clearSelection();
|
||||
text->selection.cursor = text->cursor;
|
||||
text->updateCounters();
|
||||
|
||||
// rebreak the entire document
|
||||
bv->text->fullRebreak();
|
||||
|
||||
finishUndo();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Returns false if no undo possible.
|
||||
bool textUndoOrRedo(BufferView * bv,
|
||||
limited_stack<Undo> & stack, limited_stack<Undo> & otherstack)
|
||||
{
|
||||
if (stack.empty()) {
|
||||
/*
|
||||
* Finish the undo operation in the case there was no entry
|
||||
* on the stack to perform.
|
||||
*/
|
||||
freezeUndo();
|
||||
bv->unlockInset(bv->theLockingInset());
|
||||
finishUndo();
|
||||
unFreezeUndo();
|
||||
return false;
|
||||
}
|
||||
|
||||
Undo undo = stack.top();
|
||||
stack.pop();
|
||||
finishUndo();
|
||||
|
||||
if (!undo_frozen) {
|
||||
otherstack.push(undo);
|
||||
otherstack.top().pars.clear();
|
||||
Buffer * buf = bv->buffer();
|
||||
ParagraphList & plist = buf->paragraphs();
|
||||
if (undo.first_par_offset + undo.last_par_offset <= int(plist.size())) {
|
||||
ParagraphList::iterator first = plist.begin();
|
||||
advance(first, undo.first_par_offset);
|
||||
ParagraphList::iterator last = plist.begin();
|
||||
advance(last, plist.size() - undo.last_par_offset + 1);
|
||||
otherstack.top().pars.insert(otherstack.top().pars.begin(), first, last);
|
||||
}
|
||||
otherstack.top().cursor_pos = text
|
||||
lyxerr << " undo other: " << otherstack.top() << endl;
|
||||
}
|
||||
|
||||
// Now we can unlock the inset for safety because the inset
|
||||
// pointer could be changed during the undo-function. Anyway
|
||||
// if needed we have to lock the right inset/position if this
|
||||
// is requested.
|
||||
freezeUndo();
|
||||
bv->unlockInset(bv->theLockingInset());
|
||||
bool const ret = performUndoOrRedo(bv, undo);
|
||||
unFreezeUndo();
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // 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.
|
||||
undo_finished = true;
|
||||
}
|
||||
|
||||
|
||||
bool textUndo(BufferView * bv)
|
||||
{
|
||||
return textUndoOrRedo(bv, bv->buffer()->undostack(),
|
||||
bv->buffer()->redostack());
|
||||
}
|
||||
|
||||
|
||||
bool textRedo(BufferView * bv)
|
||||
{
|
||||
return textUndoOrRedo(bv, bv->buffer()->redostack(),
|
||||
bv->buffer()->undostack());
|
||||
}
|
||||
|
||||
|
||||
void recordUndo(Undo::undo_kind kind,
|
||||
LyXText const * text, paroffset_type first, paroffset_type last)
|
||||
{
|
||||
if (!undo_frozen) {
|
||||
Buffer * buf = text->bv()->buffer();
|
||||
recordUndo(kind, const_cast<LyXText *>(text),
|
||||
first, last, buf->undostack());
|
||||
buf->redostack().clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void recordUndo(Undo::undo_kind kind, LyXText const * text, paroffset_type par)
|
||||
{
|
||||
recordUndo(kind, text, par, par);
|
||||
}
|
||||
|
||||
|
||||
void recordUndo(BufferView * bv, Undo::undo_kind kind)
|
||||
{
|
||||
recordUndo(kind, bv->text, bv->text->cursor.par());
|
||||
}
|
||||
|
62
src/undo.h
62
src/undo.h
@ -6,7 +6,9 @@
|
||||
*
|
||||
* \author Asger Alstrup
|
||||
* \author Lars Gullik Bjønnes
|
||||
* \author John Levon
|
||||
* \author André Pönitz
|
||||
* \author Jürgen Vigna
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
@ -15,11 +17,15 @@
|
||||
#define UNDO_H
|
||||
|
||||
#include "ParagraphList_fwd.h"
|
||||
#include "support/types.h"
|
||||
|
||||
class LyXText;
|
||||
class BufferView;
|
||||
|
||||
/**
|
||||
* These are the elements put on the undo stack. Each object
|
||||
* contains complete paragraphs and sufficient information
|
||||
* to restore the state. The work is done in undo_funcs.C
|
||||
* to restore the state.
|
||||
*/
|
||||
class Undo {
|
||||
public:
|
||||
@ -44,8 +50,7 @@ public:
|
||||
ATOMIC
|
||||
};
|
||||
///
|
||||
Undo(undo_kind kind, int inset_id,
|
||||
int plist,
|
||||
Undo(undo_kind kind, int text,
|
||||
int first, int last,
|
||||
int cursor, int cursor_pos,
|
||||
ParagraphList const & par_arg);
|
||||
@ -53,15 +58,8 @@ public:
|
||||
/// Which kind of operation are we recording for?
|
||||
undo_kind kind;
|
||||
|
||||
/// to what paragraph list do we belong?
|
||||
int plist;
|
||||
|
||||
/**
|
||||
* ID of hosting inset if the cursor is in one.
|
||||
* if -1, then the cursor is not in an inset.
|
||||
* if >= 0, then the cursor is in inset with given id.
|
||||
*/
|
||||
int inset_id;
|
||||
/// hosting LyXText counted from buffer begin
|
||||
int text;
|
||||
|
||||
/// Offset to the first paragraph in the main document paragraph list
|
||||
int first_par_offset;
|
||||
@ -84,4 +82,42 @@ public:
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
/// This will undo the last action - returns false if no undo possible
|
||||
bool textUndo(BufferView *);
|
||||
|
||||
/// This will redo the last undo - returns false if no redo possible
|
||||
bool textRedo(BufferView *);
|
||||
|
||||
/// Makes sure the next operation will be stored
|
||||
void finishUndo();
|
||||
|
||||
/**
|
||||
* Whilst undo is frozen, all actions do not get added
|
||||
* to the undo stack
|
||||
*/
|
||||
void freezeUndo();
|
||||
|
||||
/// Track undos again
|
||||
void unFreezeUndo();
|
||||
|
||||
/**
|
||||
* Record undo information - call with the first paragraph that will be changed
|
||||
* and the last paragraph that will be changed. So we give an inclusive
|
||||
* range.
|
||||
* This is called before you make the changes to the paragraph, and it
|
||||
* will record the original information of the paragraphs in the undo stack.
|
||||
*/
|
||||
void recordUndo(Undo::undo_kind kind,
|
||||
LyXText const * text, lyx::paroffset_type first, lyx::paroffset_type last);
|
||||
|
||||
/// Convienience: Prepare undo when change in a single paragraph.
|
||||
void recordUndo(Undo::undo_kind kind,
|
||||
LyXText const * text, lyx::paroffset_type par);
|
||||
|
||||
/// Convienience: Prepare undo for the paragraph that contains the cursor
|
||||
void recordUndo(BufferView *, Undo::undo_kind kind);
|
||||
|
||||
/// Are we avoiding tracking undos currently ?
|
||||
extern bool undo_frozen;
|
||||
|
||||
#endif // UNDO_FUNCS_H
|
||||
|
290
src/undo_funcs.C
290
src/undo_funcs.C
@ -1,290 +0,0 @@
|
||||
/**
|
||||
* \file undo_funcs.C
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Asger Alstrup
|
||||
* \author Lars Gullik Bjønnes
|
||||
* \author John Levon
|
||||
* \author André Pönitz
|
||||
* \author Jürgen Vigna
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "undo_funcs.h"
|
||||
|
||||
#include "buffer.h"
|
||||
#include "debug.h"
|
||||
#include "BufferView.h"
|
||||
#include "funcrequest.h"
|
||||
#include "iterators.h"
|
||||
#include "lyxtext.h"
|
||||
#include "paragraph.h"
|
||||
|
||||
#include "insets/updatableinset.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using std::endl;
|
||||
using lyx::paroffset_type;
|
||||
|
||||
|
||||
/// The flag used by finishUndo().
|
||||
bool undo_finished;
|
||||
|
||||
/// Whether actions are not added to the undo stacks.
|
||||
bool undo_frozen;
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
void recordUndo(BufferView * bv, Undo::undo_kind kind,
|
||||
ParagraphList & plist, paroffset_type firstpar, paroffset_type lastpar,
|
||||
limited_stack<Undo> & stack)
|
||||
{
|
||||
Buffer * buf = bv->buffer();
|
||||
|
||||
ParagraphList::iterator first = plist.begin();
|
||||
advance(first, firstpar);
|
||||
ParagraphList::iterator last = plist.begin();
|
||||
advance(last, lastpar);
|
||||
|
||||
// First, record inset id, if cursor is in one
|
||||
UpdatableInset * inset = first->inInset();
|
||||
LyXText * text = inset ? inset->getLyXText(bv) : bv->text;
|
||||
int const inset_id = inset ? inset->id() : -1;
|
||||
|
||||
// Try to find the appropriate list by counting the,
|
||||
ParIterator null = buf->par_iterator_end();
|
||||
|
||||
int pcount = 0;
|
||||
for (ParIterator it = buf->par_iterator_begin(); it != null; ++it, ++pcount)
|
||||
if (&it.plist() == &plist)
|
||||
break;
|
||||
|
||||
// And calculate a stable reference to them
|
||||
int const first_offset = firstpar;
|
||||
int const last_offset = plist.size() - lastpar;
|
||||
|
||||
// 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_offset == first_offset
|
||||
&& buf->undostack().top().last_par_offset == last_offset) {
|
||||
// No additonal undo recording needed -
|
||||
// effectively, we combine undo recordings to one.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Record the cursor position in a stable way.
|
||||
int const cursor_offset = text->cursor.par();
|
||||
|
||||
// Make and push the Undo entry
|
||||
stack.push(Undo(kind, inset_id,
|
||||
pcount,
|
||||
first_offset, last_offset,
|
||||
cursor_offset, text->cursor.pos(),
|
||||
ParagraphList()));
|
||||
|
||||
// Record the relevant paragraphs
|
||||
ParagraphList & undo_pars = stack.top().pars;
|
||||
|
||||
for (ParagraphList::iterator it = first; it != last; ++it) {
|
||||
undo_pars.push_back(*it);
|
||||
undo_pars.back().id(it->id());
|
||||
}
|
||||
undo_pars.push_back(*last);
|
||||
undo_pars.back().id(last->id());
|
||||
|
||||
// And make sure that next time, we should be combining if possible
|
||||
undo_finished = false;
|
||||
}
|
||||
|
||||
|
||||
// Returns false if no undo possible.
|
||||
bool performUndoOrRedo(BufferView * bv, Undo const & undo)
|
||||
{
|
||||
Buffer * buf = bv->buffer();
|
||||
|
||||
ParIterator null = buf->par_iterator_end();
|
||||
ParIterator plit = buf->par_iterator_begin();
|
||||
int n = undo.plist;
|
||||
for ( ; n && plit != null; ++plit, --n)
|
||||
;
|
||||
BOOST_ASSERT(plit != null);
|
||||
ParagraphList & plist = plit.plist();
|
||||
|
||||
// Remove new stuff between first and last
|
||||
{
|
||||
ParagraphList::iterator first = plist.begin();
|
||||
advance(first, undo.first_par_offset);
|
||||
ParagraphList::iterator last = plist.begin();
|
||||
advance(last, plist.size() - undo.last_par_offset);
|
||||
plist.erase(first, ++last);
|
||||
}
|
||||
|
||||
// Re-insert old stuff instead
|
||||
{
|
||||
if (plist.empty()) {
|
||||
plist.assign(undo.pars.begin(), undo.pars.end());
|
||||
} else {
|
||||
ParagraphList::iterator first = plist.begin();
|
||||
advance(first, undo.first_par_offset);
|
||||
plist.insert(first, undo.pars.begin(), undo.pars.end());
|
||||
}
|
||||
}
|
||||
|
||||
// Rebreak the entire document
|
||||
bv->text->fullRebreak();
|
||||
|
||||
// set cursor
|
||||
{
|
||||
// Get a hold of the inset for the cursor, if relevant
|
||||
UpdatableInset * inset =
|
||||
static_cast<UpdatableInset *>(
|
||||
buf->getInsetFromID(undo.inset_id));
|
||||
|
||||
LyXText * text = inset ? inset->getLyXText(bv) : bv->text;
|
||||
text->setCursorIntern(undo.cursor_par_offset, undo.cursor_pos);
|
||||
|
||||
//lyxerr << "undo, inset: " << inset << endl;
|
||||
|
||||
if (inset) {
|
||||
//lyxerr << "undo, inset owner: " << inset->owner() << endl;
|
||||
|
||||
// Magic needed to update inset internal state
|
||||
FuncRequest cmd(bv, LFUN_INSET_EDIT, "left");
|
||||
if (inset->owner())
|
||||
inset->owner()->localDispatch(cmd);
|
||||
else
|
||||
inset->localDispatch(cmd);
|
||||
}
|
||||
|
||||
// set cursor again to force the position to be the right one
|
||||
text->setCursorIntern(undo.cursor_par_offset, undo.cursor_pos);
|
||||
|
||||
// Clear any selection and set the selection
|
||||
// cursor for any new selection.
|
||||
text->clearSelection();
|
||||
text->selection.cursor = text->cursor;
|
||||
text->updateCounters();
|
||||
}
|
||||
|
||||
finishUndo();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Returns false if no undo possible.
|
||||
bool textUndoOrRedo(BufferView * bv,
|
||||
limited_stack<Undo> & stack,
|
||||
limited_stack<Undo> & otherstack)
|
||||
{
|
||||
if (stack.empty()) {
|
||||
/*
|
||||
* Finish the undo operation in the case there was no entry
|
||||
* on the stack to perform.
|
||||
*/
|
||||
freezeUndo();
|
||||
bv->unlockInset(bv->theLockingInset());
|
||||
finishUndo();
|
||||
unFreezeUndo();
|
||||
return false;
|
||||
}
|
||||
|
||||
Undo undo = stack.top();
|
||||
stack.pop();
|
||||
finishUndo();
|
||||
|
||||
if (!undo_frozen) {
|
||||
otherstack.push(undo);
|
||||
otherstack.top().pars.clear();
|
||||
Buffer * buf = bv->buffer();
|
||||
ParagraphList & plist = buf->paragraphs();
|
||||
if (undo.first_par_offset + undo.last_par_offset <= int(plist.size())) {
|
||||
ParagraphList::iterator first = plist.begin();
|
||||
advance(first, undo.first_par_offset);
|
||||
ParagraphList::iterator last = plist.begin();
|
||||
advance(last, plist.size() - undo.last_par_offset + 1);
|
||||
otherstack.top().pars.insert(otherstack.top().pars.begin(), first, last);
|
||||
}
|
||||
}
|
||||
|
||||
// Now we can unlock the inset for safety because the inset
|
||||
// pointer could be changed during the undo-function. Anyway
|
||||
// if needed we have to lock the right inset/position if this
|
||||
// is requested.
|
||||
freezeUndo();
|
||||
bv->unlockInset(bv->theLockingInset());
|
||||
bool const ret = performUndoOrRedo(bv, undo);
|
||||
unFreezeUndo();
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // 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.
|
||||
undo_finished = true;
|
||||
}
|
||||
|
||||
|
||||
bool textUndo(BufferView * bv)
|
||||
{
|
||||
return textUndoOrRedo(bv, bv->buffer()->undostack(),
|
||||
bv->buffer()->redostack());
|
||||
}
|
||||
|
||||
|
||||
bool textRedo(BufferView * bv)
|
||||
{
|
||||
return textUndoOrRedo(bv, bv->buffer()->redostack(),
|
||||
bv->buffer()->undostack());
|
||||
}
|
||||
|
||||
|
||||
void recordUndo(BufferView * bv, Undo::undo_kind kind,
|
||||
ParagraphList & plist, paroffset_type first, paroffset_type last)
|
||||
{
|
||||
if (!undo_frozen) {
|
||||
recordUndo(bv, kind, plist, first, last, bv->buffer()->undostack());
|
||||
bv->buffer()->redostack().clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void recordUndo(BufferView * bv, Undo::undo_kind kind,
|
||||
ParagraphList & plist, paroffset_type par)
|
||||
{
|
||||
recordUndo(bv, kind, plist, par, par);
|
||||
}
|
||||
|
||||
|
||||
void recordUndo(BufferView * bv, Undo::undo_kind kind)
|
||||
{
|
||||
recordUndo(bv, kind, bv->text->ownerParagraphs(), bv->text->cursor.par());
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
// -*- C++ -*-
|
||||
/**
|
||||
* \file undo_funcs.h
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Asger Alstrup
|
||||
* \author Lars Gullik Bjønnes
|
||||
* \author John Levon
|
||||
* \author André Pönitz
|
||||
* \author Jürgen Vigna
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
#ifndef UNDO_FUNCS_H
|
||||
#define UNDO_FUNCS_H
|
||||
|
||||
#include "undo.h"
|
||||
#include "ParagraphList_fwd.h"
|
||||
#include "support/types.h"
|
||||
|
||||
class BufferView;
|
||||
class Paragraph;
|
||||
|
||||
/// This will undo the last action - returns false if no undo possible
|
||||
bool textUndo(BufferView *);
|
||||
|
||||
/// This will redo the last undo - returns false if no redo possible
|
||||
bool textRedo(BufferView *);
|
||||
|
||||
/// Makes sure the next operation will be stored
|
||||
void finishUndo();
|
||||
|
||||
/**
|
||||
* Whilst undo is frozen, all actions do not get added
|
||||
* to the undo stack
|
||||
*/
|
||||
void freezeUndo();
|
||||
|
||||
/// Track undos again
|
||||
void unFreezeUndo();
|
||||
|
||||
/**
|
||||
* Record undo information - call with the first paragraph that will be changed
|
||||
* and the last paragraph that will be changed. So we give an inclusive
|
||||
* range.
|
||||
* This is called before you make the changes to the paragraph, and it
|
||||
* will record the original information of the paragraphs in the undo stack.
|
||||
*/
|
||||
void recordUndo(BufferView *, Undo::undo_kind kind,
|
||||
ParagraphList & plist, lyx::paroffset_type first, lyx::paroffset_type last);
|
||||
|
||||
/// Convienience: Prepare undo when change in a single paragraph.
|
||||
void recordUndo(BufferView *, Undo::undo_kind kind,
|
||||
ParagraphList & plist, lyx::paroffset_type par);
|
||||
|
||||
/// Convienience: Prepare undo for the paragraph that contains the cursor
|
||||
void recordUndo(BufferView *, Undo::undo_kind kind);
|
||||
|
||||
/// Are we avoiding tracking undos currently ?
|
||||
extern bool undo_frozen;
|
||||
|
||||
#endif // UNDO_FUNCS_H
|
Loading…
Reference in New Issue
Block a user