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:
André Pönitz 2003-10-14 13:01:49 +00:00
parent 5705714920
commit 5c2f0c5c46
28 changed files with 483 additions and 460 deletions

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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 \

View File

@ -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

View File

@ -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:

View File

@ -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;
}

View File

@ -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);

View File

@ -118,6 +118,8 @@ public:
///
ParagraphList * getParagraphs(int) const;
///
LyXText * getText(int) const;
///
LyXCursor const & cursor(BufferView *) const;
///
bool isOpen() const;

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -155,6 +155,8 @@ public:
///
ParagraphList * getParagraphs(int) const;
///
LyXText * getText(int) const;
///
LyXCursor const & cursor(BufferView *) const;
///
bool allowSpellcheck() const { return true; }

View File

@ -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;

View File

@ -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;
///

View File

@ -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"

View File

@ -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"

View File

@ -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)

View File

@ -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;

View File

@ -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 {

View File

@ -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,

View File

@ -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);
}

View File

@ -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"

View File

@ -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());
}

View File

@ -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

View File

@ -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());
}

View File

@ -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