commit a09ceda2c42b7ec1e03afb4166bdfcf4c52b719b
Author: Juergen Spitzmueller <[email protected]>
Date: Sat Jan 13 14:51:01 2018 +0100
Once more rework outline wrt environments.
* Fixes UNDO issues
* Takes care of some special cases
Signed-off-by: Juergen Spitzmueller <[email protected]>
---
src/Text3.cpp | 153 ++++++++++++++++++++++++++++++++++-----------------------
1 files changed, 92 insertions(+), 61 deletions(-)
diff --git a/src/Text3.cpp b/src/Text3.cpp
index f4190d2..b339e07 100644
--- a/src/Text3.cpp
+++ b/src/Text3.cpp
@@ -366,7 +366,23 @@ enum OutlineOp {
};
-static void outline(OutlineOp mode, Cursor & cur)
+static void insertSeparator(Cursor & cur, depth_type const depth)
+{
+ Buffer & buf = *cur.buffer();
+ lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK));
+ DocumentClass const & tc = buf.params().documentClass();
+ lyx::dispatch(FuncRequest(LFUN_LAYOUT, from_ascii("\"") +
tc.plainLayout().name()
+ + from_ascii("\" ignoreautonests")));
+ // FIXME: Bibitem mess!
+ if (cur.prevInset() && cur.prevInset()->lyxCode() == BIBITEM_CODE)
+ lyx::dispatch(FuncRequest(LFUN_CHAR_DELETE_BACKWARD));
+ lyx::dispatch(FuncRequest(LFUN_SEPARATOR_INSERT, "plain"));
+ while (cur.paragraph().params().depth() > depth)
+ lyx::dispatch(FuncRequest(LFUN_DEPTH_DECREMENT));
+}
+
+
+static void outline(OutlineOp mode, Cursor & cur, Text * text)
{
Buffer & buf = *cur.buffer();
pit_type & pit = cur.pit();
@@ -377,6 +393,7 @@ static void outline(OutlineOp mode, Cursor & cur)
// The final paragraph of area to be copied:
ParagraphList::iterator finish = start;
ParagraphList::iterator const end = pars.end();
+ depth_type const current_depth = cur.paragraph().params().depth();
int const thistoclevel = buf.text().getTocLevel(distance(bgn, start));
int toclevel;
@@ -411,27 +428,47 @@ static void outline(OutlineOp mode, Cursor & cur)
// Not found; do nothing
if (toclevel == Layout::NOT_IN_TOC || toclevel >
thistoclevel)
return;
+ pit_type newpit = distance(bgn, dest);
+ pit_type const len = distance(start, finish);
+ pit_type const deletepit = pit + len;
+ buf.undo().recordUndo(cur, newpit, deletepit - 1);
// If we move an environment upwards, make sure it is
- // separated from its new neighbour below.
+ // separated from its new neighbour below:
+ // If an environment of the same layout follows, and
the moved
+ // paragraph sequence does not end with a separator,
insert one.
ParagraphList::iterator lastmoved = finish;
--lastmoved;
if (start->layout().isEnvironment()
- && dest->layout() == start->layout()
- &&
!lastmoved->isEnvSeparator(lastmoved->beginOfBody())) {
- cur.pit() = distance(bgn, finish);
- cur.pos() = 0;
-
lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK));
- DocumentClass const & tc =
buf.params().documentClass();
- lyx::dispatch(FuncRequest(LFUN_LAYOUT,
from_ascii("\"") + tc.plainLayout().name()
- + from_ascii("\"
ignoreautonests")));
-
lyx::dispatch(FuncRequest(LFUN_SEPARATOR_INSERT, "plain"));
- ++finish;
+ && dest->layout() == start->layout()
+ &&
!lastmoved->isEnvSeparator(lastmoved->beginOfBody())) {
+ cur.pit() = distance(bgn, lastmoved);
+ cur.pos() = cur.lastpos();
+ insertSeparator(cur, current_depth);
cur.pit() = pit;
}
- pit_type const newpit = distance(bgn, dest);
- pit_type const len = distance(start, finish);
- pit_type const deletepit = pit + len;
- buf.undo().recordUndo(cur, newpit, deletepit - 1);
+ // Likewise, if we moved an environment upwards, make
sure it
+ // is separated from its new neighbour above.
+ // The paragraph before the target of movement
+ if (dest != bgn) {
+ ParagraphList::iterator before = dest;
+ --before;
+ // Get the parent paragraph (outer in nested
context)
+ pit_type const parent =
+ before->params().depth() > current_depth
+ ? text->depthHook(distance(bgn,
before), current_depth)
+ : distance(bgn, before);
+ // If a environment with same layout preceeds
the moved one in the new
+ // position, and there is no separator yet,
insert one.
+ if (start->layout().isEnvironment()
+ && pars[parent].layout() == start->layout()
+ &&
!before->isEnvSeparator(before->beginOfBody())) {
+ cur.pit() = distance(bgn, before);
+ cur.pos() = cur.lastpos();
+ insertSeparator(cur, current_depth);
+ cur.pit() = pit;
+ }
+ }
+ newpit = distance(bgn, dest);
pars.splice(dest, start, finish);
cur.pit() = newpit;
break;
@@ -449,26 +486,45 @@ static void outline(OutlineOp mode, Cursor & cur)
&& toclevel <= thistoclevel)
break;
}
- // One such was found:
+ // One such was found, so go on...
// If we move an environment downwards, make sure it is
- // separated from its new neighbour below.
+ // separated from its new neighbour above.
+ pit_type newpit = distance(bgn, dest);
+ buf.undo().recordUndo(cur, pit, newpit - 1);
+ // The paragraph before the target of movement
+ ParagraphList::iterator before = dest;
+ --before;
+ // Get the parent paragraph (outer in nested context)
+ pit_type const parent =
+ before->params().depth() > current_depth
+ ? text->depthHook(distance(bgn,
before), current_depth)
+ : distance(bgn, before);
+ // If a environment with same layout preceeds the moved
one in the new
+ // position, and there is no separator yet, insert one.
+ if (start->layout().isEnvironment()
+ && pars[parent].layout() == start->layout()
+ && !before->isEnvSeparator(before->beginOfBody())) {
+ cur.pit() = distance(bgn, before);
+ cur.pos() = cur.lastpos();
+ insertSeparator(cur, current_depth);
+ cur.pit() = pit;
+ }
+ // Likewise, make sure moved environments are separated
+ // from their new neighbour below:
+ // If an environment of the same layout follows, and
the moved
+ // paragraph sequence does not end with a separator,
insert one.
ParagraphList::iterator lastmoved = finish;
--lastmoved;
- if (start->layout().isEnvironment()
- && dest->layout() == start->layout()
- &&
!lastmoved->isEnvSeparator(lastmoved->beginOfBody())) {
- cur.pit() = distance(bgn, finish);
- cur.pos() = 0;
-
lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK));
- DocumentClass const & tc =
buf.params().documentClass();
- lyx::dispatch(FuncRequest(LFUN_LAYOUT,
from_ascii("\"") + tc.plainLayout().name()
- + from_ascii("\"
ignoreautonests")));
-
lyx::dispatch(FuncRequest(LFUN_SEPARATOR_INSERT, "plain"));
- ++finish;
+ if (dest != end
+ && start->layout().isEnvironment()
+ && dest->layout() == start->layout()
+ &&
!lastmoved->isEnvSeparator(lastmoved->beginOfBody())) {
+ cur.pit() = distance(bgn, lastmoved);
+ cur.pos() = cur.lastpos();
+ insertSeparator(cur, current_depth);
cur.pit() = pit;
}
- pit_type newpit = distance(bgn, dest);
- buf.undo().recordUndo(cur, pit, newpit - 1);
+ newpit = distance(bgn, dest);
pit_type const len = distance(start, finish);
pars.splice(dest, start, finish);
cur.pit() = newpit - len;
@@ -2583,54 +2639,29 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
}
break;
- case LFUN_OUTLINE_UP: {
- outline(OutlineUp, cur);
+ case LFUN_OUTLINE_UP:
+ outline(OutlineUp, cur, this);
setCursor(cur, cur.pit(), 0);
- // If we moved an environment upwards, make sure it is
- // separated from its new neighbour above.
- pit_type pit = cur.pit();
- if (pit > 0 && pars_[pit].layout().isEnvironment()
- && pars_[pit - 1].layout() == pars_[pit].layout()) {
- lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK));
- DocumentClass const & tc =
bv->buffer().params().documentClass();
- lyx::dispatch(FuncRequest(LFUN_LAYOUT, from_ascii("\"")
+ tc.plainLayout().name()
- + from_ascii("\"
ignoreautonests")));
- lyx::dispatch(FuncRequest(LFUN_SEPARATOR_INSERT,
"plain"));
- setCursor(cur, pit + 1, 0);
- }
cur.forceBufferUpdate();
needsUpdate = true;
break;
- }
case LFUN_OUTLINE_DOWN: {
- outline(OutlineDown, cur);
+ outline(OutlineDown, cur, this);
setCursor(cur, cur.pit(), 0);
- // If we moved an environment downwards, make sure it is
- // separated from its new neighbour above.
- pit_type pit = cur.pit();
- if (pit > 0 && pars_[pit].layout().isEnvironment()
- && pars_[pit - 1].layout() == pars_[pit].layout()) {
- lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK));
- DocumentClass const & tc =
bv->buffer().params().documentClass();
- lyx::dispatch(FuncRequest(LFUN_LAYOUT, from_ascii("\"")
+ tc.plainLayout().name()
- + from_ascii("\"
ignoreautonests")));
- lyx::dispatch(FuncRequest(LFUN_SEPARATOR_INSERT,
"plain"));
- setCursor(cur, pit + 1, 0);
- }
cur.forceBufferUpdate();
needsUpdate = true;
break;
}
case LFUN_OUTLINE_IN:
- outline(OutlineIn, cur);
+ outline(OutlineIn, cur, this);
cur.forceBufferUpdate();
needsUpdate = true;
break;
case LFUN_OUTLINE_OUT:
- outline(OutlineOut, cur);
+ outline(OutlineOut, cur, this);
cur.forceBufferUpdate();
needsUpdate = true;
break;