mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-22 10:00:33 +00:00
Implement inset-split (only for text insets for now) (#10260)
This commit is contained in:
parent
af1ab2caa9
commit
18f7dce3d9
@ -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.
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -2225,6 +2225,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,
|
||||
|
75
src/Text.cpp
75
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
|
||||
{
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user