[LyX/master] Implement inset-split (only for text insets for now) (#10260)
Juergen Spitzmueller
spitz at lyx.org
Thu Dec 24 09:18:39 UTC 2020
commit 18f7dce3d9877c690f3d4dbb0239a816e1d42414
Author: Juergen Spitzmueller <spitz at lyx.org>
Date: Thu Dec 24 10:48:52 2020 +0100
Implement inset-split (only for text insets for now) (#10260)
---
lib/RELEASE-NOTES | 3 ++
lib/ui/stdcontext.inc | 2 +
src/FuncCode.h | 1 +
src/LyXAction.cpp | 14 ++++++++
src/Text.cpp | 75 +++++++++++++++++++++++++++++++++++++++++++
src/Text.h | 2 +
src/Text3.cpp | 8 ++++
src/insets/InsetFlex.cpp | 6 ++-
src/insets/InsetTabular.cpp | 1 +
src/insets/InsetText.cpp | 2 +
10 files changed, 112 insertions(+), 2 deletions(-)
diff --git a/lib/RELEASE-NOTES b/lib/RELEASE-NOTES
index 6fbaba3..f73427c 100644
--- a/lib/RELEASE-NOTES
+++ b/lib/RELEASE-NOTES
@@ -95,6 +95,9 @@
* paragraph-select is a new convenience function to select the paragraph
surrounding the actual cursor position.
+* split-inset is a new convenience function that splits an inset into two at the given
+ cursor position. This is only implemented for text insets currently.
+
* tabular-style-insert: Insert a table in a specified style.
diff --git a/lib/ui/stdcontext.inc b/lib/ui/stdcontext.inc
index d189514..b4ee954 100644
--- a/lib/ui/stdcontext.inc
+++ b/lib/ui/stdcontext.inc
@@ -357,6 +357,8 @@ Menuset
Item "Paste" "paste"
Submenu "Paste Recent|e" "edit_pasterecent"
Separator
+ OptItem "Split Inset|t" "inset-split"
+ Separator
Item "Jump Back to Saved Bookmark|B" "bookmark-goto 0"
OptItem "Forward Search|F" "forward-search"
Separator
diff --git a/src/FuncCode.h b/src/FuncCode.h
index 6b970fb..9857143 100644
--- a/src/FuncCode.h
+++ b/src/FuncCode.h
@@ -493,6 +493,7 @@ enum FuncCode
LFUN_CITATION_OPEN, // sanda, 20200815
LFUN_TOOLBAR_SET, // spitz 20201217
// 385
+ LFUN_INSET_SPLIT, // jspitzm 20201222
LFUN_LASTACTION // end of the table
};
diff --git a/src/LyXAction.cpp b/src/LyXAction.cpp
index 462e397..1f0b952 100644
--- a/src/LyXAction.cpp
+++ b/src/LyXAction.cpp
@@ -2226,6 +2226,20 @@ void LyXAction::init()
{ LFUN_INSET_SETTINGS, "inset-settings", ReadOnly | AtPoint, Edit },
/*!
+ * \var lyx::FuncCode lyx::LFUN_INSET_SPLIT
+ * \li Action: Splits the current inset into two at current position.
+ * \li Syntax: inset-split [<INSET>]
+ * \li Params: <INSET>: this can be used to make sure the right kind of inset
+ is dissolved. For example "split" entry in the charstyles
+ sub-menu should only dissolve the charstyle inset, even if the
+ cursor is inside several nested insets of different type.\n
+ For values see #lyx::InsetLayout::lyxtype_ .
+ * \li Origin: spitz, 22 Dec 2020
+ * \endvar
+ */
+ { LFUN_INSET_SPLIT, "inset-split", AtPoint, Edit },
+
+/*!
* \var lyx::FuncCode lyx::LFUN_INSET_TOGGLE
* \li Action: Toggles the collapsible inset at cursor position,
or the inset we are currently in.
diff --git a/src/Text.cpp b/src/Text.cpp
index d227bd5..1f8288a 100644
--- a/src/Text.cpp
+++ b/src/Text.cpp
@@ -33,6 +33,7 @@
#include "ErrorList.h"
#include "factory.h"
#include "Font.h"
+#include "FuncRequest.h"
#include "Language.h"
#include "Layout.h"
#include "Lexer.h"
@@ -1898,6 +1899,80 @@ bool Text::dissolveInset(Cursor & cur)
}
+bool Text::splitInset(Cursor & cur)
+{
+ LASSERT(this == cur.text(), return false);
+
+ if (isMainText() || cur.inset().nargs() != 1)
+ return false;
+
+ cur.recordUndo();
+ if (cur.selection()) {
+ // start from selection begin
+ setCursor(cur, cur.selBegin().pit(), cur.selBegin().pos());
+ cur.clearSelection();
+ }
+ // save split position inside inset
+ // (we need to copy the whole inset first)
+ pos_type spos = cur.pos();
+ pit_type spit = cur.pit();
+ // some things only need to be done if the inset has content
+ bool const inset_non_empty = cur.lastpit() != 0 || cur.lastpos() != 0;
+
+ // move right before the inset
+ cur.popBackward();
+ cur.resetAnchor();
+ // remember position outside inset
+ pos_type ipos = cur.pos();
+ pit_type ipit = cur.pit();
+ // select inset ...
+ ++cur.pos();
+ cur.setSelection();
+ // ... and copy
+ cap::copySelectionToTemp(cur);
+ cur.clearSelection();
+ cur.resetAnchor();
+ // paste copied inset
+ cap::pasteFromTemp(cur, cur.buffer()->errorList("Paste"));
+ cur.forceBufferUpdate();
+
+ // if the inset has text, cut after split position
+ // and paste to new inset
+ if (inset_non_empty) {
+ // go back to first inset
+ cur.text()->setCursor(cur, ipit, ipos);
+ cur.forwardPos();
+ setCursor(cur, spit, spos);
+ cur.resetAnchor();
+ setCursor(cur, cur.lastpit(), getPar(cur.lastpit()).size());
+ cur.setSelection();
+ cap::cutSelectionToTemp(cur);
+ cur.setMark(false);
+ cur.selHandle(false);
+ cur.resetAnchor();
+ Cursor dummy = cur;
+ dummy.pos() = dummy.pit() = 0;
+ if (cur.bv().checkDepm(dummy, cur))
+ cur.forceBufferUpdate();
+ // Move out of and jump over inset
+ cur.popBackward();
+ ++cur.pos();
+
+ // enter new inset
+ cur.forwardPos();
+ cur.setCursor(cur);
+ cur.resetAnchor();
+ cur.text()->selectAll(cur);
+ cutSelection(cur, false);
+ cap::pasteFromTemp(cur, cur.buffer()->errorList("Paste"));
+ cur.text()->setCursor(cur, 0, 0);
+ }
+
+ cur.finishUndo();
+ return true;
+}
+
+
void Text::getWord(CursorSlice & from, CursorSlice & to,
word_location const loc) const
{
diff --git a/src/Text.h b/src/Text.h
index 4defd94..1410828 100644
--- a/src/Text.h
+++ b/src/Text.h
@@ -245,6 +245,8 @@ public:
// Dissolve the inset under cursor
/// FIXME: replace Cursor with DocIterator.
bool dissolveInset(Cursor & cur);
+ /// FIXME: replace Cursor with DocIterator.
+ bool splitInset(Cursor & cur);
///
bool selectWordWhenUnderCursor(Cursor & cur, word_location);
/// Change the case of the word at cursor position.
diff --git a/src/Text3.cpp b/src/Text3.cpp
index 07d7e80..61b64ef 100644
--- a/src/Text3.cpp
+++ b/src/Text3.cpp
@@ -1370,6 +1370,14 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
break;
}
+ case LFUN_INSET_SPLIT: {
+ if (splitInset(cur)) {
+ needsUpdate = true;
+ cur.forceBufferUpdate();
+ }
+ break;
+ }
+
case LFUN_GRAPHICS_SET_GROUP: {
InsetGraphics * ins = graphics::getCurrentGraphicsInset(cur);
if (!ins)
diff --git a/src/insets/InsetFlex.cpp b/src/insets/InsetFlex.cpp
index 4da349f..e607610 100644
--- a/src/insets/InsetFlex.cpp
+++ b/src/insets/InsetFlex.cpp
@@ -94,6 +94,7 @@ bool InsetFlex::getStatus(Cursor & cur, FuncRequest const & cmd,
FuncStatus & flag) const
{
switch (cmd.action()) {
+ case LFUN_INSET_SPLIT:
case LFUN_INSET_DISSOLVE:
if (!cmd.argument().empty()) {
InsetLayout const & il = getLayout();
@@ -102,7 +103,7 @@ bool InsetFlex::getStatus(Cursor & cur, FuncRequest const & cmd,
if (il.lyxtype() == type
|| (il.name() == DocumentClass::plainInsetLayout().name()
&& type == InsetLyXType::CHARSTYLE)) {
- FuncRequest temp_cmd(LFUN_INSET_DISSOLVE);
+ FuncRequest temp_cmd(cmd.action());
return InsetCollapsible::getStatus(cur, temp_cmd, flag);
} else
return false;
@@ -117,6 +118,7 @@ bool InsetFlex::getStatus(Cursor & cur, FuncRequest const & cmd,
void InsetFlex::doDispatch(Cursor & cur, FuncRequest & cmd)
{
switch (cmd.action()) {
+ case LFUN_INSET_SPLIT:
case LFUN_INSET_DISSOLVE:
if (!cmd.argument().empty()) {
InsetLayout const & il = getLayout();
@@ -126,7 +128,7 @@ void InsetFlex::doDispatch(Cursor & cur, FuncRequest & cmd)
if (il.lyxtype() == type
|| (il.name() == DocumentClass::plainInsetLayout().name()
&& type == InsetLyXType::CHARSTYLE)) {
- FuncRequest temp_cmd(LFUN_INSET_DISSOLVE);
+ FuncRequest temp_cmd(cmd.action());
InsetCollapsible::doDispatch(cur, temp_cmd);
} else
cur.undispatched();
diff --git a/src/insets/InsetTabular.cpp b/src/insets/InsetTabular.cpp
index 181e68c..b3e8bd8 100644
--- a/src/insets/InsetTabular.cpp
+++ b/src/insets/InsetTabular.cpp
@@ -4226,6 +4226,7 @@ bool InsetTableCell::getStatus(Cursor & cur, FuncRequest const & cmd,
{
bool enabled = true;
switch (cmd.action()) {
+ case LFUN_INSET_SPLIT:
case LFUN_INSET_DISSOLVE:
enabled = false;
break;
diff --git a/src/insets/InsetText.cpp b/src/insets/InsetText.cpp
index 5c4d32c..8e0500d 100644
--- a/src/insets/InsetText.cpp
+++ b/src/insets/InsetText.cpp
@@ -320,6 +320,7 @@ void InsetText::doDispatch(Cursor & cur, FuncRequest & cmd)
fixParagraphsFont();
break;
+ case LFUN_INSET_SPLIT:
case LFUN_INSET_DISSOLVE: {
bool const main_inset = text_.isMainText();
bool const target_inset = cmd.argument().empty()
@@ -351,6 +352,7 @@ bool InsetText::getStatus(Cursor & cur, FuncRequest const & cmd,
FuncStatus & status) const
{
switch (cmd.action()) {
+ case LFUN_INSET_SPLIT:
case LFUN_INSET_DISSOLVE: {
bool const main_inset = text_.isMainText();
bool const target_inset = cmd.argument().empty()
More information about the lyx-cvs
mailing list