From 3a16b6dbf7044e2c6b90279a4ed10508247dd46f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Spitzm=C3=BCller?= Date: Sun, 28 Jun 2009 08:40:34 +0000 Subject: [PATCH] Implement LFUN_OUTLINE_DRAGMOVE. Contribution by Rob Oakes. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@30278 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/FuncCode.h | 1 + src/LyXAction.cpp | 21 +++++++++++++ src/Text3.cpp | 76 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+) diff --git a/src/FuncCode.h b/src/FuncCode.h index c67fef02ad..360885ac5b 100644 --- a/src/FuncCode.h +++ b/src/FuncCode.h @@ -344,6 +344,7 @@ enum FuncCode // 260 LFUN_OUTLINE_IN, LFUN_OUTLINE_OUT, + LFUN_OUTLINE_DRAGMOVE, // roakes 20090601 LFUN_PARAGRAPH_MOVE_DOWN, LFUN_PARAGRAPH_MOVE_UP, LFUN_BUFFER_TOGGLE_COMPRESSION, // bpeng 20060427 diff --git a/src/LyXAction.cpp b/src/LyXAction.cpp index ae14ada7b3..0d80f5e316 100644 --- a/src/LyXAction.cpp +++ b/src/LyXAction.cpp @@ -1987,6 +1987,26 @@ void LyXAction::init() * \endvar */ { LFUN_OUTLINE_OUT, "outline-out", Noop, Edit }, + +/*! + * \var lyx::FuncCode lyx::LFUN_OUTLINE_DRAGMOVE + * \li Action: Moves the document section associated with the specified + heading to a specified location. Both the heading and the + target paragraph are specified by the paragraph ID numbers. + * \li Notion: The heading is a paragraph with style Part/Chapter/Section/ + etc. Id number of the paragraph is not the sequential number + seen on the screen, but an internal number that is unique + for all opened buffers (documents). + * \li Syntax: outline-dragmove + * \li Params: : paragraph id of the section heading which + is to be moved. \n + : the paragraph id where the section + will be moved to. + * \li Origin: Rob Oakes, 22 June 2009 + * \endvar + */ + { LFUN_OUTLINE_DRAGMOVE, "outline-dragmove", Noop, Edit }, + /*! * \var lyx::FuncCode lyx::LFUN_INSET_EDIT * \li Action: Edit the inset at cursor with an external application, @@ -1997,6 +2017,7 @@ void LyXAction::init() * \li Origin: JSpitzm, 27 Apr 2006 * \endvar */ + { LFUN_INSET_EDIT, "inset-edit", ReadOnly, Edit }, /*! diff --git a/src/Text3.cpp b/src/Text3.cpp index cf76341c82..d44d6b171c 100644 --- a/src/Text3.cpp +++ b/src/Text3.cpp @@ -306,6 +306,71 @@ enum OutlineOp { }; +static void dragMove(Cursor & cur, int moveId, int moveToId) +{ + // Create Pointers to Buffers + Buffer & buf_move = *cur.buffer(); + DocIterator dit_move = buf_move.getParFromID(moveId); + DocIterator dit_dest = buf_move.getParFromID(moveToId); + + pit_type & pit_move = dit_move.pit(); + pit_type & pit_dest = dit_dest.pit(); + ParagraphList & pars = dit_move.text()->paragraphs(); + + // Create References to the Paragraphs to Be Moved + ParagraphList::iterator const bgn = pars.begin(); + ParagraphList::iterator dest_start = boost::next(bgn, pit_dest); + + // The first paragraph of the area to be copied: + ParagraphList::iterator start = boost::next(bgn, pit_move); + // The final paragraph of area to be copied: + ParagraphList::iterator finish = start; + ParagraphList::iterator const end = pars.end(); + + DocumentClass const & tc = buf_move.params().documentClass(); + + int const thistoclevel = start->layout().toclevel; + int toclevel; + + // Move out (down) from this section header + if (finish != end) + ++finish; + // Seek the one (on same level) below + for (; finish != end; ++finish) { + toclevel = finish->layout().toclevel; + if (toclevel != Layout::NOT_IN_TOC + && toclevel <= thistoclevel) + break; + } + + // Do we need to set insets' buffer_ members, because we copied + // some stuff? We'll assume we do and reset it otherwise. + bool set_buffers = true; + + if (start == pars.begin()) + // Nothing to Move + return; + if (start == dest_start) + // Nothing to Move + return; + + pit_type const len = distance(start, finish); + pars.insert(dest_start, start, finish); + pars.erase(start,finish); + + if (set_buffers) + // FIXME: This only really needs doing for the newly + // introduced paragraphs. Something like: + // pit_type const numpars = distance(start, finish); + // start = boost::next(bgn, pit); + // finish = boost::next(start, numpars); + // for (; start != finish; ++start) + // start->setBuffer(buf); + // But while this seems to work, it is kind of fragile. + buf_move.inset().setBuffer(buf_move); +} + + static void outline(OutlineOp mode, Cursor & cur) { Buffer & buf = *cur.buffer(); @@ -2023,6 +2088,16 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) cur.buffer()->updateLabels(); needsUpdate = true; break; + + case LFUN_OUTLINE_DRAGMOVE: { + int const move_id = convert(cmd.getArg(0)); + int const move_to_id = convert(cmd.getArg(1)); + dragMove(cur, move_id, move_to_id); + setCursor(cur, cur.pit(), 0); + cur.buffer()->updateLabels(); + needsUpdate = true; + break; + } default: LYXERR(Debug::ACTION, "Command " << cmd << " not DISPATCHED by Text"); @@ -2411,6 +2486,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, case LFUN_OUTLINE_DOWN: case LFUN_OUTLINE_IN: case LFUN_OUTLINE_OUT: + case LFUN_OUTLINE_DRAGMOVE: // FIXME: LyX is not ready for outlining within inset. enable = isMainText(cur.bv().buffer()) && cur.paragraph().layout().toclevel != Layout::NOT_IN_TOC;