On Thu, Apr 27, 2006 at 07:49:45AM +0300, Martin Vermeer wrote:
> On Wed, Apr 26, 2006 at 11:19:02PM +0200, Jean-Marc Lasgouttes wrote:
> > >>>>> "Martin" == Martin Vermeer <[EMAIL PROTECTED]> writes:
> > 
> > Martin> Committed to trunk:
> > 
> > Martin>     Outlining improvements/fixes
> > 
> > Do you think the corresponding 1.4 patch could go in for 1.4.2? 
> 
> I would have to prepare one first...

Attached.

I noticed that the 1.4 environment has already diverged quite a lot from
1.5, so this needs to get some thorough testing of its own. E.g.,
non-numbered headers are _not_ part of the ToC here.

- Martin
 
Index: LyXAction.C
===================================================================
--- LyXAction.C (revision 13690)
+++ LyXAction.C (working copy)
@@ -240,6 +240,10 @@ void LyXAction::init()
                { LFUN_DOWN_PARAGRAPH, "paragraph-down", ReadOnly | NoUpdate},
                { LFUN_DOWN_PARAGRAPHSEL, "paragraph-down-select", ReadOnly },
                { LFUN_GOTO_PARAGRAPH, "paragraph-goto", ReadOnly },
+               { LFUN_OUTLINE_UP, "outline-up", Noop },
+               { LFUN_OUTLINE_DOWN, "outline-down", Noop },
+               { LFUN_OUTLINE_IN, "outline-in", Noop },
+               { LFUN_OUTLINE_OUT, "outline-out", Noop },
                { LFUN_PARAGRAPH_SPACING, "paragraph-spacing", Noop },
                { LFUN_UP_PARAGRAPH, "paragraph-up", ReadOnly | NoUpdate},
                { LFUN_UP_PARAGRAPHSEL, "paragraph-up-select", ReadOnly },
Index: BufferView_pimpl.C
===================================================================
--- BufferView_pimpl.C  (revision 13690)
+++ BufferView_pimpl.C  (working copy)
@@ -49,6 +49,7 @@
 #include "ParagraphParameters.h"
 #include "pariterator.h"
 #include "rowpainter.h"
+#include "toc.h"
 #include "undo.h"
 #include "vspace.h"
 
@@ -1042,6 +1043,11 @@ FuncStatus BufferView::Pimpl::getStatus(
        case LFUN_INSERT_LABEL:
        case LFUN_BOOKMARK_SAVE:
        case LFUN_GOTO_PARAGRAPH:
+       // FIXME handle non-trivially
+       case LFUN_OUTLINE_UP:
+       case LFUN_OUTLINE_DOWN:
+       case LFUN_OUTLINE_IN:
+       case LFUN_OUTLINE_OUT:
        case LFUN_GOTOERROR:
        case LFUN_GOTONOTE:
        case LFUN_REFERENCE_GOTO:
@@ -1196,6 +1202,25 @@ bool BufferView::Pimpl::dispatch(FuncReq
                break;
        }
 
+       case LFUN_OUTLINE_UP:
+               lyx::toc::outline(lyx::toc::Up, cursor_);
+               cursor_.text()->setCursor(cursor_, cursor_.pit(), 0);
+               updateCounters(*buffer_);
+               break;
+       case LFUN_OUTLINE_DOWN:
+               lyx::toc::outline(lyx::toc::Down, cursor_);
+               cursor_.text()->setCursor(cursor_, cursor_.pit(), 0);
+               updateCounters(*buffer_);
+               break;
+       case LFUN_OUTLINE_IN:
+               lyx::toc::outline(lyx::toc::In, cursor_);
+               updateCounters(*buffer_);
+               break;
+       case LFUN_OUTLINE_OUT:
+               lyx::toc::outline(lyx::toc::Out, cursor_);
+               updateCounters(*buffer_);
+               break;
+                                 
        case LFUN_GOTOERROR:
                bv_funcs::gotoInset(bv_, InsetBase::ERROR_CODE, false);
                break;
Index: frontends/qt2/QTocDialog.C
===================================================================
--- frontends/qt2/QTocDialog.C  (revision 13690)
+++ frontends/qt2/QTocDialog.C  (working copy)
@@ -32,8 +32,11 @@ QTocDialog::QTocDialog(QToc * form)
        if (w)
                w->hide();
 
-       connect(closePB, SIGNAL(clicked()),
-               form, SLOT(slotClose()));
+       connect(closePB, SIGNAL(clicked()), form, SLOT(slotClose()));
+       connect(moveupPB, SIGNAL(clicked()), this, SLOT(moveup_adaptor()));
+       connect(movednPB, SIGNAL(clicked()), this, SLOT(movedn_adaptor()));
+       connect(moveinPB, SIGNAL(clicked()), this, SLOT(movein_adaptor()));
+       connect(moveoutPB, SIGNAL(clicked()), this, SLOT(moveout_adaptor()));
 }
 
 
@@ -60,12 +63,50 @@ void QTocDialog::select_adaptor(QListVie
 }
 
 
+void QTocDialog::enableButtons(bool enable)
+{
+       updatePB->setEnabled(enable);
+
+       if (!form_->canOutline())
+               enable = false;
+
+       moveupPB->setEnabled(enable);
+       movednPB->setEnabled(enable);
+       moveinPB->setEnabled(enable);
+       moveoutPB->setEnabled(enable);
+}
+
+
 void QTocDialog::update_adaptor()
 {
        form_->update();
 }
 
 
+void QTocDialog::moveup_adaptor()
+{
+       form_->moveup();
+}
+
+
+void QTocDialog::movedn_adaptor()
+{
+       form_->movedn();
+}
+
+
+void QTocDialog::movein_adaptor()
+{
+       form_->movein();
+}
+
+
+void QTocDialog::moveout_adaptor()
+{
+       form_->moveout();
+}
+
+
 void QTocDialog::closeEvent(QCloseEvent * e)
 {
        form_->slotWMHide();
Index: frontends/qt2/ui/QTocDialogBase.ui
===================================================================
--- frontends/qt2/ui/QTocDialogBase.ui  (revision 13690)
+++ frontends/qt2/ui/QTocDialogBase.ui  (working copy)
@@ -168,7 +168,51 @@
                     </property>
                     <property stdset="1">
                         <name>text</name>
-                        <string>&amp;Update</string>
+                        <string>U&amp;pdate</string>
+                    </property>
+                </widget>
+               <widget>
+                    <class>QPushButton</class>
+                    <property stdset="1">
+                        <name>name</name>
+                        <cstring>moveupPB</cstring>
+                    </property>
+                    <property stdset="1">
+                        <name>text</name>
+                        <string>&amp;Up</string>
+                    </property>
+               </widget>
+               <widget>
+                    <class>QPushButton</class>
+                    <property stdset="1">
+                        <name>name</name>
+                        <cstring>movednPB</cstring>
+                    </property>
+                    <property stdset="1">
+                        <name>text</name>
+                        <string>&amp;Down</string>
+                    </property>
+                </widget>
+               <widget>
+                    <class>QPushButton</class>
+                    <property stdset="1">
+                        <name>name</name>
+                        <cstring>moveinPB</cstring>
+                    </property>
+                    <property stdset="1">
+                        <name>text</name>
+                        <string>&amp;In</string>
+                    </property>
+                </widget>
+               <widget>
+                    <class>QPushButton</class>
+                    <property stdset="1">
+                        <name>name</name>
+                        <cstring>moveoutPB</cstring>
+                    </property>
+                    <property stdset="1">
+                        <name>text</name>
+                        <string>&amp;Out</string>
                     </property>
                 </widget>
                 <spacer>
Index: frontends/qt2/QTocDialog.h
===================================================================
--- frontends/qt2/QTocDialog.h  (revision 13690)
+++ frontends/qt2/QTocDialog.h  (working copy)
@@ -24,11 +24,17 @@ class QTocDialog : public QTocDialogBase
 public:
        QTocDialog(QToc * form);
        ~QTocDialog();
+       ///
+       void enableButtons(bool enable = true);
 public slots:
        void activate_adaptor(int);
        void depth_adaptor(int);
        void select_adaptor(QListViewItem *);
        void update_adaptor();
+       void moveup_adaptor();
+       void movedn_adaptor();
+       void movein_adaptor();
+       void moveout_adaptor();
 protected:
        void closeEvent(QCloseEvent * e);
 private:
Index: frontends/qt2/QToc.C
===================================================================
--- frontends/qt2/QToc.C        (revision 13690)
+++ frontends/qt2/QToc.C        (working copy)
@@ -48,6 +48,8 @@ void QToc::build_dialog()
 
        // Manage the cancel/close button
        bcview().setCancel(dialog_->closePB);
+       type_ = toc::getType(controller().params().getCmdName());
+       dialog_->enableButtons();
 }
 
 
@@ -67,6 +69,8 @@ void QToc::updateType()
                        setTitle(guiname);
                }
        }
+       type_ = type;
+       dialog_->enableButtons();
 }
 
 
@@ -83,6 +87,8 @@ void QToc::updateToc(int newdepth)
        string type;
        if (!choice.empty())
                type = choice[dialog_->typeCO->currentItem()];
+       type_ = type;
+       dialog_->enableButtons();
 
        toc::Toc const & contents = controller().getContents(type);
 
@@ -107,7 +113,9 @@ void QToc::updateToc(int newdepth)
        QListViewItem * last = 0;
        QListViewItem * parent = 0;
        QListViewItem * item;
-
+       QListViewItem * selected_item = 0;
+       bool multiple = false;
+       
        // Yes, it is this ugly. Two reasons - root items must have
        // a QListView parent, rather than QListViewItem; and the
        // TOC can move in and out an arbitrary number of levels
@@ -157,14 +165,34 @@ void QToc::updateToc(int newdepth)
                item->setOpen(iter->depth < depth_);
                curdepth = iter->depth;
                last = item;
+
+               // Recognise part past the counter
+               if (iter->str.substr(iter->str.find(' ') + 1) == text_) {
+                       if (selected_item == 0)
+                               selected_item = item;
+                       else
+                               // more than one match
+                               multiple = true;
+               }
        }
 
        dialog_->tocLV->setUpdatesEnabled(true);
        dialog_->tocLV->update();
+       if (!multiple) {
+               dialog_->tocLV->scrollBy(0, selected_item->itemPos() 
+                       - dialog_->tocLV->height() / 2);
+               dialog_->tocLV->setSelected(selected_item, true);
+       }
        setTitle(fromqstr(dialog_->typeCO->currentText()));
 }
 
 
+bool QToc::canOutline()
+{
+       return controller().canOutline(type_);
+}
+
+
 void QToc::select(string const & text)
 {
        toc::Toc::const_iterator iter = toclist.begin();
@@ -180,6 +208,8 @@ void QToc::select(string const & text)
                return;
        }
 
+       // Lop off counter part and save:
+       text_ = text.substr(text.find(' ') + 1);
        controller().goTo(*iter);
 }
 
@@ -190,5 +220,34 @@ void QToc::set_depth(int depth)
                updateToc(depth);
 }
 
+
+void QToc::moveup()
+{
+       controller().outline(toc::Up);
+       updateToc(depth_);
+}
+
+
+void QToc::movedn()
+{
+       controller().outline(toc::Down);
+       updateToc(depth_);
+}
+
+
+void QToc::movein()
+{
+       controller().outline(toc::In);
+       updateToc(depth_);
+}
+
+
+void QToc::moveout()
+{
+       controller().outline(toc::Out);
+       updateToc(depth_);
+}
+
+
 } // namespace frontend
 } // namespace lyx
Index: frontends/qt2/QToc.h
===================================================================
--- frontends/qt2/QToc.h        (revision 13690)
+++ frontends/qt2/QToc.h        (working copy)
@@ -33,6 +33,9 @@ private:
        /// update the listview
        void updateToc(int newdepth);
 
+       ///
+       bool canOutline();
+
        /// update the float types
        void updateType();
 
@@ -42,6 +45,15 @@ private:
        /// set the depth
        void set_depth(int depth);
 
+       /// Move header up/down/in/out in list (outlining)
+       void moveup();
+       ///
+       void movedn();
+       ///
+       void movein();
+       ///
+       void moveout();
+
        virtual void apply() {}
 
        /// update dialog
@@ -55,6 +67,12 @@ private:
 
        /// depth of list shown
        int depth_;
+
+       /// Store selected item's string
+       std::string text_;
+
+       /// Store ToC list type
+       std::string type_;
 };
 
 } // namespace frontend
Index: frontends/controllers/ControlToc.C
===================================================================
--- frontends/controllers/ControlToc.C  (revision 13690)
+++ frontends/controllers/ControlToc.C  (working copy)
@@ -8,9 +8,12 @@
  * Full author contact details are available in file CREDITS.
  */
 
+#include <sstream>
+
 #include <config.h>
 
 #include "ControlToc.h"
+#include "funcrequest.h"
 #include "gettext.h"
 
 using std::vector;
@@ -34,6 +37,31 @@ void ControlToc::goTo(toc::TocItem const
 }
 
 
+bool ControlToc::canOutline(string const & type)
+{
+       return type == "TOC";
+}
+
+
+void ControlToc::outline(toc::OutlineOp op)
+{
+       switch (op) {
+       case toc::Up:
+               kernel().dispatch(FuncRequest(LFUN_OUTLINE_UP));
+               break;
+       case toc::Down:
+               kernel().dispatch(FuncRequest(LFUN_OUTLINE_DOWN));
+               break;
+       case toc::In:
+               kernel().dispatch(FuncRequest(LFUN_OUTLINE_IN));
+               break;
+       case toc::Out:
+               kernel().dispatch(FuncRequest(LFUN_OUTLINE_OUT));
+               break;
+       }
+}
+
+
 vector<string> const ControlToc::getTypes() const
 {
        return toc::getTypes(kernel().buffer());
Index: frontends/controllers/ControlToc.h
===================================================================
--- frontends/controllers/ControlToc.h  (revision 13690)
+++ frontends/controllers/ControlToc.h  (working copy)
@@ -38,6 +38,12 @@ public:
 
        /// Given a type, returns the contents
        toc::Toc const getContents(std::string const & type) const;
+
+       /// Apply the selected outlining operation
+       void outline(toc::OutlineOp op);
+
+       /// Test if outlining operation is possible
+       bool canOutline(std::string const & type);
 };
 
 } // namespace frontend
Index: lfuns.h
===================================================================
--- lfuns.h     (revision 13690)
+++ lfuns.h     (working copy)
@@ -357,6 +357,11 @@ enum kb_action {
        LFUN_BIBDB_ADD,
        LFUN_BIBDB_DEL,
        LFUN_INSERT_CITATION,
+       LFUN_OUTLINE_UP,                 // Vermeer 20060323
+       // 275
+       LFUN_OUTLINE_DOWN,
+       LFUN_OUTLINE_IN,
+       LFUN_OUTLINE_OUT,
 
        LFUN_LASTACTION                  // end of the table
 };
Index: toc.C
===================================================================
--- toc.C       (revision 13690)
+++ toc.C       (working copy)
@@ -15,11 +15,12 @@
 
 #include "buffer.h"
 #include "bufferparams.h"
+#include "cursor.h"
 #include "FloatList.h"
 #include "funcrequest.h"
 #include "LyXAction.h"
 #include "paragraph.h"
-#include "pariterator.h"
+#include "undo.h"
 
 #include "frontends/LyXView.h"
 
@@ -167,5 +168,111 @@ void asciiTocList(string const & type, B
 }
 
 
+void outline(OutlineOp mode,  LCursor & cur)
+{
+       recordUndo(cur);
+       Buffer * buf = & cur.buffer();
+       pit_type & pit = cur.pit();
+       ParagraphList & pars = buf->text().paragraphs();
+       ParagraphList::iterator bgn = pars.begin();
+       ParagraphList::iterator s = boost::next(bgn, pit);
+       ParagraphList::iterator p = s;
+       ParagraphList::iterator end = pars.end();
+
+       LyXTextClass::const_iterator lit =
+               buf->params().getLyXTextClass().begin();
+       LyXTextClass::const_iterator const lend =
+               buf->params().getLyXTextClass().end();
+
+       int const thistoclevel = s->layout()->toclevel;
+       int toclevel;
+       switch (mode) {
+               case Up: {
+                       if (p != end)
+                               ++p;
+                       for (; p != end; ++p) {
+                               toclevel = p->layout()->toclevel;
+                               if (toclevel != LyXLayout::NOT_IN_TOC 
+                                   && toclevel <= thistoclevel) {
+                                       break;  
+                               }
+                       }
+                       ParagraphList::iterator q = s;
+                       if (q != bgn)
+                               --q;
+                       else
+                               break;
+                       for (; q != bgn; --q) {
+                               toclevel = q->layout()->toclevel;
+                               if (toclevel != LyXLayout::NOT_IN_TOC 
+                                   && toclevel <= thistoclevel) {
+                                       break;  
+                               }
+                       }
+                       pit_type const newpit = std::distance(pars.begin(), q);
+                       pit_type const len = std::distance(s, p);
+                       pit += len;
+                       pars.insert(q, s, p);
+                       s = boost::next(pars.begin(), pit);
+                       ParagraphList::iterator t = boost::next(s, len);
+                       pit = newpit;
+                       pars.erase(s, t);
+               break;
+               }
+               case Down: {
+                          if (p != end)
+                               ++p;
+                       for (; p != end; ++p) {
+                               toclevel = p->layout()->toclevel;
+                               if (toclevel != LyXLayout::NOT_IN_TOC 
+                                   && toclevel <= thistoclevel) {
+                                       break;  
+                               }
+                       }
+                       ParagraphList::iterator q = p;
+                       if (q != end)
+                               ++q;
+                       else
+                               break;
+                       for (; q != end; ++q) {
+                               toclevel = q->layout()->toclevel;
+                               if (toclevel != LyXLayout::NOT_IN_TOC 
+                                   && toclevel <= thistoclevel) {
+                                       break;  
+                               }
+                       }
+                       pit_type const newpit = std::distance(pars.begin(), q);
+                       pit_type const len = std::distance(s, p);
+                       pars.insert(q, s, p);
+                       s = boost::next(pars.begin(), pit);
+                       ParagraphList::iterator t = boost::next(s, len);
+                       pit = newpit - len;
+                       pars.erase(s, t);
+               break;
+               }
+               case In:
+                       for (; lit != lend; ++lit) {
+                               if ((*lit)->toclevel == thistoclevel + 1 &&
+                                   s->layout()->labeltype == 
(*lit)->labeltype) {
+                                       s->layout((*lit));
+                                       break;
+                               }
+                       }
+               break;
+               case Out:
+                       for (; lit != lend; ++lit) {
+                               if ((*lit)->toclevel == thistoclevel - 1 &&
+                                   s->layout()->labeltype == 
(*lit)->labeltype) {
+                                       s->layout((*lit));
+                                       break;
+                               }
+                       }
+               break;
+               default:
+               break;
+       }
+}
+
+
 } // namespace toc
 } // namespace lyx
Index: toc.h
===================================================================
--- toc.h       (revision 13690)
+++ toc.h       (working copy)
@@ -20,6 +20,8 @@
 #include <vector>
 #include <string>
 
+#include "pariterator.h"
+
 class Buffer;
 class LyXView;
 class Paragraph;
@@ -72,8 +74,7 @@ std::string const getGuiName(std::string
 inline
 bool operator==(TocItem const & a, TocItem const & b)
 {
-       return a.id_ == b.id_ && a.str == b.str;
-       // No need to compare depth.
+       return a.id_ == b.id_ && a.str == b.str && a.depth == b.depth;
 }
 
 
@@ -84,6 +85,18 @@ bool operator!=(TocItem const & a, TocIt
 }
 
 
+/// the type of outline operation
+enum OutlineOp {
+       Up, // Move this header with text down
+       Down,   // Move this header with text up
+       In, // Make this header deeper
+       Out // Make this header shallower
+};
+
+
+void outline(OutlineOp, LCursor &);
+
+
 } // namespace toc
 } // namespace lyx
 

Attachment: pgpJrwrd1a4ai.pgp
Description: PGP signature

Reply via email to