]> git.lyx.org Git - features.git/commitdiff
Implement LFUN_OUTLINE_DRAGMOVE.
authorJürgen Spitzmüller <spitz@lyx.org>
Sun, 28 Jun 2009 08:40:34 +0000 (08:40 +0000)
committerJürgen Spitzmüller <spitz@lyx.org>
Sun, 28 Jun 2009 08:40:34 +0000 (08:40 +0000)
Contribution by Rob Oakes.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@30278 a592a061-630c-0410-9148-cb99ea01b6c8

src/FuncCode.h
src/LyXAction.cpp
src/Text3.cpp

index c67fef02ad37b7a09b579447c65ce880140fd7d0..360885ac5beaf21fd26cd28ed423e3a9e3334a74 100644 (file)
@@ -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
index ae14ada7b30a6b86b13cf0c35daf7119d6e075ba..0d80f5e316c894f2984cf91df5f18e1dbe08cf2e 100644 (file)
@@ -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 <PAR_ID_SECTION> <PAR_ID_DROP_POSITION>
+ * \li Params: <PAR_ID_SECTION>: paragraph id of the section heading which
+                                 is to be moved. \n
+               <PAR_ID_DROP_POSITION>: 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 },
 
 /*!
index cf76341c8216ea230716d6bc0276fb67845b1343..d44d6b171c3921257a1ea49e0139e62966bf58ff 100644 (file)
@@ -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<int>(cmd.getArg(0));
+               int const move_to_id = convert<int>(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;