From 92613ac63c7ca55b81570fd81f9f228168736a14 Mon Sep 17 00:00:00 2001 From: Juergen Spitzmueller Date: Mon, 1 Jan 2018 12:34:39 +0100 Subject: [PATCH] Implement environment-split before and previous Possibility to add an environment before the current one and to append and environment from outside the nesting scope. This commit includes all fixes that went in during testing these functions in master. It also moves the menu items from Edit to Insert. --- lib/bind/de/menus.bind | 2 +- lib/bind/menus.bind | 2 +- lib/ui/stdmenus.inc | 2 +- src/LyXAction.cpp | 8 +++-- src/Text3.cpp | 67 ++++++++++++++++++++++++++++++++----- src/frontends/qt4/Menus.cpp | 37 ++++++++++++++++---- 6 files changed, 98 insertions(+), 20 deletions(-) diff --git a/lib/bind/de/menus.bind b/lib/bind/de/menus.bind index fb72535c1d..e9dc373184 100644 --- a/lib/bind/de/menus.bind +++ b/lib/bind/de/menus.bind @@ -113,7 +113,7 @@ Format 4 \bind "M-a Down" "outline-down" -\bind "M-a Return" "environment-split" +\bind "M-a Return" "command-alternatives environment-split ; environment-split previous" \bind "M-a S-Return" "environment-split outer" # Obsolete Tastenbelegung: in die persönliche *.bind Datei kopieren und diff --git a/lib/bind/menus.bind b/lib/bind/menus.bind index 458d9c9bcb..a27fab842d 100644 --- a/lib/bind/menus.bind +++ b/lib/bind/menus.bind @@ -126,7 +126,7 @@ Format 4 \bind "M-p Up" "outline-up" \bind "M-p Down" "outline-down" -\bind "M-p Return" "environment-split" +\bind "M-p Return" "command-alternatives environment-split ; environment-split previous" \bind "M-p S-Return" "environment-split outer" diff --git a/lib/ui/stdmenus.inc b/lib/ui/stdmenus.inc index c3a0c841a3..1b79adb31b 100644 --- a/lib/ui/stdmenus.inc +++ b/lib/ui/stdmenus.inc @@ -134,7 +134,6 @@ Menuset # obvious what the context is for the others) OptItem "Increase List Depth|I" "depth-increment" OptItem "Decrease List Depth|D" "depth-decrement" - EnvironmentSeparators OptItem "Dissolve Inset" "inset-dissolve" OptItem "TeX Code Settings...|C" "inset-settings ert" # 'a' shortcut to match Insert entry, shouldn't clash with Table Settings @@ -393,6 +392,7 @@ Menuset Item "Hyperlink...|k" "href-insert" Item "Footnote|F" "footnote-insert" Item "Marginal Note|M" "marginalnote-insert" + EnvironmentSeparators Arguments Item "TeX Code" "ert-insert" Item "Program Listing[[Menu]]" "listing-insert" diff --git a/src/LyXAction.cpp b/src/LyXAction.cpp index e0d4e473d7..7cd103b1c4 100644 --- a/src/LyXAction.cpp +++ b/src/LyXAction.cpp @@ -1513,9 +1513,13 @@ void LyXAction::init() /*! * \var lyx::FuncCode lyx::LFUN_ENVIRONMENT_SPLIT * \li Action: Splits the current environment with a Separator. - * \li Syntax: environment-split [outer] + * \li Syntax: environment-split [before|outer|previous] * \li Params: outer: If this is given, LyX will split the outermost environment in - * the current nesting hierarchy. + the current nesting hierarchy.\n + previous: If this is given, LyX will split the environment in the previous + paragraph (is there is one).\n + before: If this is given, the new environment will be appended rather than + prepended. * \li Origin: spitz, 23 Dec 2012 * \endvar */ diff --git a/src/Text3.cpp b/src/Text3.cpp index af244002d1..9c4c7f9f7c 100644 --- a/src/Text3.cpp +++ b/src/Text3.cpp @@ -1491,36 +1491,74 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) case LFUN_ENVIRONMENT_SPLIT: { bool const outer = cmd.argument() == "outer"; + bool const previous = cmd.argument() == "previous"; + bool const before = cmd.argument() == "before"; + bool const normal = cmd.argument().empty(); Paragraph const & para = cur.paragraph(); - docstring layout = para.layout().name(); + docstring layout; + if (para.layout().isEnvironment()) + layout = para.layout().name(); depth_type split_depth = cur.paragraph().params().depth(); - if (outer) { - // check if we have an environment in our nesting hierarchy + depth_type nextpar_depth = 0; + if (outer || previous) { + // check if we have an environment in our scope pit_type pit = cur.pit(); Paragraph cpar = pars_[pit]; while (true) { - if (pit == 0 || cpar.params().depth() == 0) + if (pit == 0) break; --pit; cpar = pars_[pit]; + if (layout.empty() && previous + && cpar.layout().isEnvironment() + && cpar.params().depth() <= split_depth) + layout = cpar.layout().name(); if (cpar.params().depth() < split_depth && cpar.layout().isEnvironment()) { - layout = cpar.layout().name(); + if (!previous) + layout = cpar.layout().name(); split_depth = cpar.params().depth(); } + if (cpar.params().depth() == 0) + break; } } - if (cur.pos() > 0) + if ((outer || normal) && cur.pit() < cur.lastpit()) { + // save nesting of following paragraph + Paragraph cpar = pars_[cur.pit() + 1]; + nextpar_depth = cpar.params().depth(); + } + if (before) + cur.top().setPitPos(cur.pit(), 0); + if (before || cur.pos() > 0) lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK)); + else if (previous && cur.nextInset() && cur.nextInset()->lyxCode() == SEPARATOR_CODE) + lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK, "inverse ignoresep")); if (outer) { while (cur.paragraph().params().depth() > split_depth) lyx::dispatch(FuncRequest(LFUN_DEPTH_DECREMENT)); } DocumentClass const & tc = bv->buffer().params().documentClass(); - lyx::dispatch(FuncRequest(LFUN_LAYOUT, tc.plainLayout().name())); + lyx::dispatch(FuncRequest(LFUN_LAYOUT, from_ascii("\"") + tc.plainLayout().name() + + from_ascii("\" ignoreautonests"))); lyx::dispatch(FuncRequest(LFUN_SEPARATOR_INSERT, "plain")); - lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK, "inverse")); + if (before) { + cur.backwardPos(); + lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK, "inverse ignoresep")); + while (cur.paragraph().params().depth() < split_depth) + lyx::dispatch(FuncRequest(LFUN_DEPTH_INCREMENT)); + } + else + lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK, "inverse")); lyx::dispatch(FuncRequest(LFUN_LAYOUT, layout)); + if ((outer || normal) && nextpar_depth > 0) { + // restore nesting of following paragraph + DocIterator scur = cur; + cur.forwardPar(); + while (cur.paragraph().params().depth() < nextpar_depth) + lyx::dispatch(FuncRequest(LFUN_DEPTH_INCREMENT)); + cur.setCursor(scur); + } break; } @@ -3180,6 +3218,19 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, enable = res; break; } + else if (cmd.argument() == "previous") { + // look if we have an environment in the previous par + pit_type pit = cur.pit(); + Paragraph cpar = pars_[pit]; + if (pit > 0) { + --pit; + cpar = pars_[pit]; + enable = cpar.layout().isEnvironment(); + break; + } + enable = false; + break; + } else if (cur.paragraph().layout().isEnvironment()) { enable = true; break; diff --git a/src/frontends/qt4/Menus.cpp b/src/frontends/qt4/Menus.cpp index c97d23d44c..ecae50d581 100644 --- a/src/frontends/qt4/Menus.cpp +++ b/src/frontends/qt4/Menus.cpp @@ -1856,33 +1856,56 @@ void MenuDefinition::expandEnvironmentSeparators(BufferView const * bv) return; pit_type pit = bv->cursor().selBegin().pit(); + pos_type pos = bv->cursor().selBegin().pos(); Paragraph const & par = text->getPar(pit); docstring const curlayout = par.layout().name(); docstring outerlayout; + docstring prevlayout; depth_type current_depth = par.params().depth(); - // check if we have an environment in our nesting hierarchy + // check if we have an environment in our scope Paragraph cpar = par; while (true) { - if (pit == 0 || cpar.params().depth() == 0) + if (pit == 0) break; --pit; cpar = text->getPar(pit); + if (cpar.layout().isEnvironment() && prevlayout.empty() + && cpar.params().depth() <= current_depth) + prevlayout = cpar.layout().name(); if (cpar.params().depth() < current_depth && cpar.layout().isEnvironment()) { outerlayout = cpar.layout().name(); current_depth = cpar.params().depth(); } + if (cpar.params().depth() == 0) + break; } if (par.layout().isEnvironment()) { - docstring const label = - bformat(_("Start New Environment (%1$s)"), + docstring label = bformat(_("Separated %1$s Above"), translateIfPossible(curlayout)); add(MenuItem(MenuItem::Command, toqstr(label), - FuncRequest(LFUN_ENVIRONMENT_SPLIT))); + FuncRequest(LFUN_ENVIRONMENT_SPLIT, + from_ascii("before")))); + if (!par.layout().keepempty || pos > 0 || !text->isFirstInSequence(pit)) { + label = bformat(_("Separated %1$s Below"), + translateIfPossible(curlayout)); + add(MenuItem(MenuItem::Command, toqstr(label), + FuncRequest(LFUN_ENVIRONMENT_SPLIT))); + } + } + else if (!prevlayout.empty()) { + docstring const label = + bformat(_("Separated %1$s Below"), + translateIfPossible(prevlayout)); + add(MenuItem(MenuItem::Command, toqstr(label), + FuncRequest(LFUN_ENVIRONMENT_SPLIT, + from_ascii("previous")))); } if (!outerlayout.empty()) { - docstring const label = - bformat(_("Start New Parent Environment (%1$s)"), + docstring const label = (outerlayout == curlayout) ? + bformat(_("Separated Outer %1$s Below"), + translateIfPossible(outerlayout)) : + bformat(_("Separated %1$s Below"), translateIfPossible(outerlayout)); add(MenuItem(MenuItem::Command, toqstr(label), FuncRequest(LFUN_ENVIRONMENT_SPLIT,