[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